EF Code сначала Eager загрузки и проблема OrderBy - PullRequest
2 голосов
/ 06 июля 2011

У меня есть две сущности под названием Категория и Продукт с отношением 1: n.

Я хочу получить категорию с дочерними элементами, в которой будут находиться дочерние элементы.

Это мой linq:

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

Этот запрос принудительно выполняется со следующим исключением из-за orderby.

Выражение «Включить путь» должно ссылаться для свойства навигации, определенного на тип. Используйте пунктирные пути для справочные навигационные свойства и Оператор Выбрать для коллекции навигационные свойства. Имя параметра: путь

Ответы [ 2 ]

5 голосов
/ 06 июля 2011

Загруженные данные не могут быть упорядочены или отфильтрованы. Это ограничение linq-to-entity, и единственный способ упорядочить отношения в базе данных - использовать проекцию:

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();
1 голос
/ 06 июля 2011

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); }
    }
}
...