无法在Repository类中创建非泛型LINQ函数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法在Repository类中创建非泛型LINQ函数相关的知识,希望对你有一定的参考价值。

我正在尝试为对象Page创建一个存储库。

我想有非通用的LINQ查询,但似乎无法让它们工作,

我只能创建它们,如果它们是通用的并且在帮助程序类中,如果建议在Helper类中使用这种类型的函数,请告诉我,如果有,请告诉我原因。

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);
    }
}

当我尝试使IQueryable非泛型时,我收到以下错误:

公共类PageRepository有一个问题:

必须在非泛型静态类中定义扩展方法

也:

'IQueryable'不包含'WhereStatusType'的定义,并且没有扩展方法'WhereStatusType'接受类型'IQueryable'的第一个参数可以找到(你是否缺少using指令或汇编引用?)

我相信这是一个简单的解决方案,谢谢你的帮助。此外,如果我接近这个错误,任何建议将不胜感激。

Edit:

虽然为上面的代码建议使用FirstOfDefault(),但我也希望在返回List<PageViewModel>时使用该函数(我可能过度简化了代码/示例),例如:

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;
    }
}
答案

错误消息告诉您这里到底发生了什么。如果你想要一个扩展方法 - 一个第一个参数使用this关键字的方法,就像你的例子一样 - 那么它需要在非泛型静态类中定义,比如你的PageHelper

如果您不喜欢这种方法,可以定义一个非扩展方法,如下所示:

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);
    }

}
另一答案

正如@asherber所说,你的LINQ查询是不对的。您正在比较p.Aliasp.Alias

此外,看起来你想要一个FirstOrDefault()

以上是关于无法在Repository类中创建非泛型LINQ函数的主要内容,如果未能解决你的问题,请参考以下文章

为什么要使用泛型?泛型和非泛型对比

《精通C#》第十二章 Linq

从非泛型类调用抽象泛型类中定义的方法的最佳方法是啥

OfType 的使用

为啥 C# 无法从非泛型静态方法的签名推断泛型类型参数类型?

如何为 useHitory() 覆盖非泛型类型,例如 @types/History?