简体   繁体   中英

Unable to create non-generic LINQ function within Repository class

I'm trying to create a Repository for an Object Page .

I would like to have non-generic LINQ queries but can't seem to get them working,

I am only able to create them if they are generic and in a helper class, and please let me know if it is recommended to have this type of function in a Helper Class, let me know the reasoning if so.

public class PageRepository
{
    public PageViewModel GetPageById(string oid)
    {
        using (var db = new AppDbContext())
        {
            Page page = db.Pages
                //This is what I cannot get working
                .WhereStatusType(StatusType.Published);

            return GetPageView(page);
        }
    }

    //I would like the below to work
    //Tried generic (below), also non-generic <Page> but doesn't work
    internal static IQueryable<T> WhereStatusType<T>(this IQueryable<T> query, StatusType statusType = StatusType.Published)
        where T : Page
    {
        return query.Where(p => p.StatusType == statusType);
    }

}

//Below is working, but don't want it in a helper
public static class PageHelper
{
    internal static IQueryable<T> WhereStatusType<T>(this IQueryable<T> query, StatusType statusType = StatusType.Published)
        where T : Page
    {
        return query.Where(p => p.StatusType == statusType);
    }
}

When I attempt to make the IQueryable non-generic, I receive the following errors:

public class PageRepository has an issue:

Extension method must be defined in a non-generic static class

Also:

'IQueryable' does not contain a definition for 'WhereStatusType' and no extension method 'WhereStatusType' accepting a first argument of type 'IQueryable' could be found (are you missing a using directive or an assembly reference?)

I'm sure it is a simple solution, thank you for the help. Also, if I am approaching this incorrectly, any advice would be greatly appreciated.

Edit:

While FirstOfDefault() is suggested for the above code, I am also looking to use the function when returning List<PageViewModel> (I may have over-simplified the code/example), for example:

public List<PageViewModel> GetPages()
{
    using (var context = new AppDbContext())
    {

        List<Page> pages = new List<Page>();
        pages = context.Pages.AsNoTracking()
            .WhereStatusType(StatusType.Published)
            .ToList();

        if (pages != null)
        {
            List<PageViewModel> pageViewModels = new List<PageViewModel>();
            foreach (Page p in pages)
                pageViewModels.Add(GetPageView(p));

            return pageViewModels;
        }
        else
            return null;
    }
}

The error message tells you exactly what's going on here. If you want an extension method -- a method whose first parameter uses the this keyword, like your example -- then it needs to be defined in a non-generic static class, like your PageHelper .

If you don't like that approach, you could define a non-extension method, something like this:

public class PageRepository
{
    public PageViewModel GetPageById(string oid)
    {
        using (var db = new AppDbContext())
        {
            Page page = GetPagesWithStatus(db.Pages, StatusType.Published);

            return GetPageView(page);
        }
    }

    internal IQueryable<Page> GetPagesWithStatus(IQueryable<Page> query, StatusType statusType)
    {
        return query.Where(p => p.StatusType == statusType);
    }

}

As @asherber mentioned, your LINQ query isn't right. You are comparing p.Alias to p.Alias

Also, it looks like you want a FirstOrDefault() in there.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM