【问题标题】:Can I use an extension method in Entity Framework SubQuery?我可以在实体框架子查询中使用扩展方法吗?
【发布时间】:2014-10-26 18:32:54
【问题描述】:

我正在尝试整合使用实体框架访问不同表的逻辑。我创建了一个扩展方法,用于从该人参加的注册实体中提取所有注册:

public static IEnumerable<Registration> Attending(this IEnumerable<Registration> registrations)
{
    return registrations.Where(r => r.Status == RegistrationStatus.Paid || r.Status == RegistrationStatus.Assigned || r.Status == RegistrationStatus.Completed);
}

这非常适合这样的查询:

var attendees = db.Registrations.Attending().ToList();

但在子查询中使用时不起作用:

ProductTotals = db.Products.Where(p => p.EventID == ev.Id).Select(p => new ProductSummaryViewModel
{
    ProductID = p.ProductID,
    ProductName = p.Name,
    Registrations = p.Registrations.Attending().Count(),
}).ToList();

我收到以下错误:

LINQ to Entities 无法识别该方法 'System.Collections.Generic.IEnumerable1[Registration] Attending(System.Collections.Generic.IEnumerable1[注册])' 方法,并且该方法不能翻译成商店表达式。

有没有办法在子查询中重用该代码?

【问题讨论】:

  • 您可以在Select之前使用AsEnumerable()来执行内存中的操作。尽管您失去了在数据库级别执行它的优势。
  • 如果您在 EF 查询中使用该方法,则该方法应该接受并返回 IQueryable 而不是 IEnumerable,否则不会在数据库上执行查询。
  • @Servy 谢谢,我注意到了同样的事情并将其更改为使用 IQueryable

标签: c# sql-server asp.net-mvc linq entity-framework


【解决方案1】:

您要实现的主要目标是重用定义Attending 含义的谓词。您可以通过将表达式存储在一个只读变量中来做到这一点,该变量可供您的应用程序中需要它的任何人使用,例如在静态类 ExpressionConstants 中。

public static readonly Expression<Func<Registration, bool>> IsAttending = 
    r => r.Status == RegistrationStatus.Paid
      || r.Status == RegistrationStatus.Assigned
      || r.Status == RegistrationStatus.Completed;

那你就可以了

var attendees = db.Registrations.Where(ExpressionConstants.IsAttending).ToList();

并在子查询中使用:

ProductTotals = db.Products.Where(p => p.EventID == ev.Id).Select(p => new ProductSummaryViewModel
{
    ProductID = p.ProductID,
    ProductName = p.Name,
    Registrations = p.Registrations.AsQueryable() // AsQueryable()
                     .Where(ExpressionConstants.IsAttending).Count(),
})

AsQueryable() 是必要的,因为p.Registrations 可能是ICollection

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-12
    • 1970-01-01
    相关资源
    最近更新 更多