Как отсортировать связанные объекты с активной загрузкой в ​​ADO.NET Entity Framework - PullRequest
2 голосов
/ 15 июня 2009

Привет,

Рассматривая примеры таблиц Northwind Customers, Orders и OrderDetails Я бы хотел загрузить соответствующие сущности, соответствующие таблицам, упомянутым выше, и все же мне нужно не упорядочить дочерние сущности в базе данных перед извлечением сущностей.

Базовый корпус:

var someQueryable = from customer in northwindContext.Customers.Include("Orders.OrderDetails") 
select customer;

но мне также нужно отсортировать Orders и OrderDetails на стороне базы данных (перед извлечением этих объектов в память) по некоторому случайному столбцу в этих таблицах. Возможно ли это без какой-либо проекции, как в T-SQL? Не имеет значения, использует ли решение e-SQL или LINQ to Entities. Я искал в Интернете, но не был удовлетворен найденными ответами, поскольку они в основном включают проецирование данных на какой-то анонимный тип, а затем повторно запрашивают этот анонимный тип, чтобы получить дочерние объекты в нужном вам порядке. Кроме того, использование CreateSourceQuery (), кажется, не вариант для меня, поскольку мне нужно получить данные в том виде, в котором они находятся на стороне базы данных, с быстрой загрузкой, но просто упорядочив дочерние объекты. То есть я хочу сделать «ORDER BY» перед выполнением любого запроса, а затем извлечь объекты в порядке, который я хотел бы. Заранее спасибо за любые рекомендации. Как личное замечание, прошу прощения за прямой язык, так как я очень зол на Microsoft за то, что выпустил EF в такой незрелой форме даже по сравнению с Linq для SQL (который, похоже, медленно уходит). Я надеюсь, что эта версия EF станет намного лучше и без существенных ошибок в версии .NET FX 4.0.

Ответы [ 3 ]

8 голосов
/ 15 июня 2009

На самом деле у меня есть Совет , который решает именно эту проблему.

Сортировка связанных объектов не «поддерживается», но при использовании проекционного подхода Крейг показывает И , опираясь на что-то под названием «Исправление отношений», вы можете получить что-то очень похожее, работая:

Если вы сделаете это:

var projection = from c in ctx.Customers
                 select new {
                       Customer = c, 
                       Orders = c.Orders.OrderByDescending( 
                                 o => o.OrderDate 
                             )
                 };

foreach(var anon in projection )
{
   anon.Orders //is sorted (because of the projection)
   anon.Customer.Orders // is sorted too! because of relationship fixup
}

Что означает, что если вы сделаете это:

var customers = projection.AsEnumerable().Select(x => x.Customer);

у вас будут клиенты, которые отсортировали заказы!

См. Совет для получения дополнительной информации.

Надеюсь, это поможет

Alex

2 голосов
/ 15 июня 2009

Вы путаете две разные проблемы. Первый способ материализации сущностей в базе данных, второй способ получения упорядоченного списка. Тип EntityCollection не является упорядоченным списком. В вашем примере customer.Orders является коллекцией EntityCollection.

С другой стороны, если вы хотите получить список в определенном порядке, вы, безусловно, можете это сделать; это просто не может быть в свойстве типа EntityCollection. Например:

from c in northwindContext.Customers
orderby c.SomeField
select new {
    Name = c.Name,
    Orders = from o in c.Orders
             orderby c.SomeField
             select new {
                SomeField = c.SomeField
             }
}

Обратите внимание, что звонков в "Включить" нет. Потому что я проецирую, это не нужно.

Entity Framework может работать не так, как вы ожидаете, исходя из LINQ to SQL, но он работает Будьте осторожны с осуждением, прежде чем вы поймете это; решение о том, что это не работает, помешает вам узнать, как это работает.

0 голосов
/ 16 июня 2009

Спасибо вам обоим. Я понимаю, что могу использовать проекцию, чтобы достичь того, чего я хотел, но я подумал, что это может быть простой способ сделать это, поскольку в мире T-SQL это вполне возможно с несколькими вложенными запросами (или объединениями) и порядком. С другой стороны, разделение проблем звучит разумно, и мы сейчас находимся в области сущностей, поэтому я буду использовать способ, который вы оба рекомендовали, хотя я должен признать, что это проще и понятнее достичь в LINQ to SQL с помощью AssociateWith.

С уважением.

...