EF Code First 预加载和 OrderBy 问题

发布于 2024-11-18 11:36:20 字数 399 浏览 3 评论 0原文

我有两个名为“类别”和“产品”的实体,具有 1:n 关系。

我想要一个带有子项的类别,子项是有序的。

这是我的 linq:

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

由于 orderby,此查询强制执行以下异常。

包含路径表达式必须引用 到定义的导航属性 类型。使用点路径 参考导航属性和 用于集合的 Select 运算符 导航属性。参数名称: 路径

I have two entities called Category and Product with 1:n relation.

I want to get a Category with its childs that childs be in order.

This is my linq:

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

This query enforce with the below exception because of orderby.

The Include path expression must refer
to a navigation property defined on
the type. Use dotted paths for
reference navigation properties and
the Select operator for collection
navigation properties. Parameter name:
path

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

祁梦 2024-11-25 11:36:20

急切加载的数据无法排序或过滤。这是 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();

Eager loaded data cannot be ordered or filtered. That is linq-to-entities limitation and the only way how to order relations in the database is by using projection:

var data =  _db.Polls
               .Where(c => c.CategoryID == pollID)
               .Select(c => new 
                   {
                       Pool = c,
                       Products = c.Products.OrderBy(p => p.ProductID)
                   })
               .SingelOrDefault();

You can project to anonymous or custom type but you cannot project to mapped type (for example Poll).

Another way is dividing this to two queries and use explicit loading:

var poll = _db.Polls.SingleOrDefault(c => c.CategoryID == pollID);
_db.Entry(poll).Collection(c => c.Products)
               .Query()
               .OrderBy(p =>.ProductID)
               .Load();
╄→承喏 2024-11-25 11:36:20

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

...要访问每个 CategoryProducts 有序列表,您可以将一个属性添加到 <代码>类别像这样:

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

Include has to reference a navigation property, which means you can't include an OrderBy(). Instead of this:

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

...you'll have to use this:

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

...to access an ordered list of Products for each Category, you could add a property to Category like this:

class Category
{
    public IEnumerable<Product> OrderedProducts
    {
        get { return this.Products.OrderBy(p => p.ProductID); }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文