【问题标题】:EF Code first Eager loading and OrderBy problemEF Code first Eager loading 和 OrderBy 问题
【发布时间】:2011-09-29 12:58:51
【问题描述】:
我有两个实体,分别称为 Category 和 Product,具有 1:n 关系。
我想获得一个类别及其子级,这些子级是有序的。
这是我的 linq:
_db.Categories.Where(c => c.CategoryID == catID)
.Include(c => c.Products.OrderBy(p => p.ProductID))
.SingleOrDefault();
由于 orderby,此查询强制执行以下异常。
包含路径表达式必须引用
到定义的导航属性
方式。使用虚线路径
参考导航属性和
用于收集的 Select 运算符
导航属性。参数名称:
路径
【问题讨论】:
标签:
linq
entity-framework
linq-to-entities
ef-code-first
eager-loading
【解决方案1】:
无法对急切加载的数据进行排序或过滤。这是 linq-to-entities 的限制,在数据库中排序关系的唯一方法是使用投影:
var data = _db.Polls
.Where(c => c.CategoryID == pollID)
.Select(c => new
{
Pool = c,
Products = c.Products.OrderBy(p => p.ProductID)
})
.SingelOrDefault();
您可以投影到匿名或自定义类型,但不能投影到映射类型(例如Poll)。
另一种方法是将其分为两个查询并使用显式加载:
var poll = _db.Polls.SingleOrDefault(c => c.CategoryID == pollID);
_db.Entry(poll).Collection(c => c.Products)
.Query()
.OrderBy(p =>.ProductID)
.Load();
【解决方案2】:
Include 必须引用导航属性,这意味着您不能包含OrderBy()。而不是这个:
_db.Categories
.Where(c => c.CategoryID == catID)
.Include(c => c.Products.OrderBy(p => p.ProductID))
.SingleOrDefault();
...你必须使用这个:
_db.Categories
.Where(c => c.CategoryID == catID)
.Include(c => c.Products)
.SingleOrDefault();
...要访问每个Category 的Products 的有序列表,您可以向Category 添加一个属性,如下所示:
class Category
{
public IEnumerable<Product> OrderedProducts
{
get { return this.Products.OrderBy(p => p.ProductID); }
}
}