Как мне стремиться загрузить запись прародителя в EF 4.1 - PullRequest
3 голосов
/ 18 ноября 2011

Я использую EF4.1 и пытаюсь понять правильный подход к загрузке. У меня есть система ввода заказов с таблицей Vendor (grandparent), Order Buy (parent) и PO2Item (child). Модель выглядит так ModelScreenImage

Я хочу начать с записи PO2Item и загрузить поставщика. Я думал, что мог бы просто использовать .Include () так:

var po = (from item in context.PO2Item.Include("PurchaseOrder.Vendor").AsNoTracking()
            where item.OrderLineItemId == lineItem.CostSourceLineItemId
            select item.PurchaseOrder).FirstOrDefault();

Это загружает запись PurchaseOrder, но po.Vendor имеет значение null. Я читал книгу Джулии Лерман, и в Главе 4 указывалось, что я могу использовать Load, но я думаю, что 4.1, должно быть, изменил это с 4.0, потому что Load, кажется, не определена, и нет такой вещи как VendorReference. В конце концов я копался в ObjectContext и смог сделать это:

   if (po!=null)
   {
       context.GetObjectContext().LoadProperty(po, "Vendor");  
   }

, который загружает Продавца, но у меня такое чувство, что я упускаю что-то гораздо более простое. Почему не работает Include ("PurchaseOrder.Vendor")

ОБНОВЛЕНИЕ, основанное на ответе Крейга.

Вместо того, чтобы приводить результат как ObjectQuery <> (сам по себе крутой трюк), я просто написал запрос в два этапа

var links = from link in context.PO2Item.Include("PurchaseOrder.Vendor").AsNoTracking()
            where link.OrderLineItemId == lineItem.CostSourceLineItemId
            select link;

var po_2_item = links.FirstOrDefault();
return po_2_item == null ? null : po_2_item.PurchaseOrder;

Для возвращенного заказа на поставку (если он существует) поставщик установлен правильно.

См. этот ответ для более элегантного решения.

Ответы [ 2 ]

2 голосов
/ 18 ноября 2011

.Include() работает с формой возвращенного запроса.

Ваш запрос возвращает PurchaseOrder, а не PO2Item.

Вам нужно что-то более похожее (Угадайте навведите здесь - вы можете использовать DbSet - настроить соответственно):

var po = ((ObjectQuery<PurchaseOrder>)
         (from item in context.PO2Item
          where item.OrderLineItemId == lineItem.CostSourceLineItemId
          select item.PurchaseOrder))
         .Include("Vendor")
         .AsNoTracking()
         .FirstOrDefault();
1 голос
/ 18 ноября 2011

Я знаю, что на это уже есть ответ, но почему бы просто не сделать это?

// Get the purchase order (with Vendor) that has the given PO2Item
var po = context.PurchaseOrder.Include("Vendor").AsNoTracking().FirstOrDefault(
    o => o.PO2Item.Any(i => i.OrderLineItemId == lineItem.CostSourceLineItemId));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...