Учитывая следующий запрос LINQ to Entities (EF4) ...
var documents =
from doc in context.Documents
.Include(d => d.Batch.FinancialPeriod)
.Include(d => d.Batch.Contractor)
.Include(d => d.GroupTypeHistory.Select(gth => gth.GroupType))
.Include(d => d.Items.Select(i => i.Versions))
.Include(d => d.Items.Select(i => i.Versions.Select(v => v.ProductPackPeriodic.ProductPack.Product.HomeDelivery)))
.Include(d => d.Items.Select(i => i.Versions.Select(v => v.ProductPackPeriodic.ProductPack.Product.Manufacturer)))
.Include(d => d.Items.Select(i => i.Versions.Select(v => v.ProductPackPeriodic.ProductPeriodic)))
.Include(d => d.Items.Select(i => i.Versions.Select(v => v.ProductPackPeriodic.SpecialContainerIndicator)))
.Include(d => d.Items.Select(i => i.Versions.Select(v => v.Endorsements.Select(e => e.Periodic))))
where doc.ID == this.documentID
select doc;
Document document = documents.FirstOrDefault();
Где ...
- Документ всегда будет иметь Пакет, который в свою очередь всегда будет иметь
финансовый период и подрядчик
- Документ всегда будет иметь один или
подробнее GroupTypeHistory, каждый из которых всегда будет иметь GroupType
- Документ будет иметь ноль или более элементов, которые в свою очередь будут иметь один
или более версии
- Версия будет иметь ноль или один ProductPackPeriodic
- ProductPackPeriodic всегда будет иметь один ProductPack и один
ProductPeriodic, вместе с нулем или одним SpecialContainerIndicator
- ProductPack всегда будет иметь один Product
- Товар будет иметь ноль или одного производителя, а ноль или один HomeDelivery
- версия будет иметь ноль или более Одобрений, каждая из которых будет иметь одну Периодическую
Приведенный выше запрос LINQ генерирует худший TSQL, который я когда-либо видел, с некоторыми включенными таблицами, включенными несколько раз (возможно, потому что на них ссылаются в запросе несколько раз), и занимает значительно больше времени, чем мне бы хотелось (соответствующие таблицы могут содержать миллионы строк, но это не причина).
Я знаю, что должен быть лучший способ написать его (принимая во внимание все различные ссылочные типы, которые я описал выше), что приведет к лучшему TSQL, но каждая версия, которую я пробую, не может правильно вернуть данные .
Кто-нибудь может помочь мне найти лучшее решение?
Если бы мне было легче понять, будь я пишу TSQL напрямую, я бы посмотрел на что-то вроде следующего ...
select *
from Document d
inner join Batch b
inner join FinancialPeriod fp on b.FinancialPeriodID = fp.FinancialPeriodID
inner join Contractor c on b.ContractorID = c.ContractorID
on d.BatchID = b.BatchID
inner join DocumentGroupType dgt on d.DocumentID = dgt.DocumentID
left join Item i
left join ItemVersion iv
left join ProductPackPeriodic ppp
inner join ProductPack pack
inner join Product p
left join Manufacturer m on p.ManufacturerID = m.ManufacturerID
left join HomeDeliveryProduct hdp on p.ProductID = hdp.ProductID
on pack.ProductID = p.ProductID
on ppp.ProductPackID = pack.ProductPackID
inner join ProductPeriodic pp on ppp.ProductPeriodicID = pp.ProductPeriodicID
left join SpecialContainerIndicator sci on ppp.SpecialContainerIndicatorCode = sci.SpecialContainerIndicatorCode
on iv.ProductPackPeriodicID = ppp.ProductPackPeriodicID
left join ItemVersionEndorsement ive
inner join EndorsementPeriodic ep on ive.EndorsementPeriodicID = ep.EndorsementPeriodicID
on iv.ItemVersionID = ive.ItemVersionID
on i.ItemID = iv.ItemID
on d.DocumentID = i.DocumentID
where d.DocumentID = 33 -- example value
Это также может прояснить требования к отношениям.
Заранее спасибо.