我尝试使用Entity Framework整合访问不同表的逻辑。我创建了一个扩展方法,用于从我所在的注册实体中提取所有注册:
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无法识别该方法 &#39; {System.Collections.Generic.IEnumerable {1}} 1 [注册])&#39; 方法,并且此方法无法转换为商店表达式。
有没有办法在子查询中重用该代码?
答案 0 :(得分:8)
您尝试实现的主要功能是重用定义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
。