EF Code First 急加载和 OrderBy 问题

3

我有两个实体分别叫做“类别”和“产品”,它们之间存在1:n的关系。

我想要获取一个类别及其子项,使得子项按顺序排列。

这是我的linq语句:

 _db.Categories.Where(c => c.CategoryID == catID)
    .Include(c => c.Products.OrderBy(p => p.ProductID))
    .SingleOrDefault();

由于orderby的原因,此查询会出现以下异常。

包含路径表达式必须引用类型上定义的导航属性。对于引用导航属性,请使用点路径;对于集合导航属性,请使用Select运算符。参数名称:path

2个回答

6

预加载的数据不能被排序或过滤。这是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();

如果要访问每个类别的有序产品列表,您可以像这样向类别添加属性:

class Category
{
    public IEnumerable<Product> OrderedProducts
    {
        get { return this.Products.OrderBy(p => p.ProductID); }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接