2

我有两个实体称为类别和产品与1:n的关系。EF代码第一次急切加载和OrderBy问题

我想要得到一个类别与它的孩子,孩子是为了。

这是我的LINQ:

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

该查询执行与以下异常,因为排序依据的。

包含路径表达式必须将 指向 类型上定义的导航属性。使用 参考导航属性的虚线路径和 导航属性的选择运算符的 。参数名: 路径

回答

1

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

...访问的Products有序列表中为每个Category,你可以将属性添加到Category像这样:

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

不能订购或过滤急切加载的数据。这是LINQ到实体的限制,以及如何通过使用投影命令在数据库中关系的唯一途径:

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