2013-04-22 15 views
0

У меня есть некоторые «сложные» сущности, образованные другими объектами. Например, 'Order' Entity:Получить Entity, состоящий из дочерних объектов в Entity Framework

  • Заказать
  • OrderDetail (ребенок)
  • OrderDetailsDiscount (ребенок ребенка)
  • OrderPayment
  • OrderState

Код для Класс заказа:

[MetadataType(typeof(OrderMetadata))] 
public partial class Order 
{ 
    public OrderPaymentStatus PaymentStatus { 
     get { return Paid ? OrderPaymentStatus.Paid : OrderPaymentStatus.Pending; } 
    } 

    public bool Paid { 
     get { 
      return TotalPaid >= Total; 
     } 
    } 

    public decimal TotalPaid { 
     get { 
      return OrderPayments.Sum(p => p.Amount); 
     } 
    } 

    public decimal TotalRefund { 
     get { 
      return OrderRefunds.Sum(p => p.Amount); 
     } 
    } 

    public decimal TotalDebt { 
     get { 
      return Total - TotalPaid + TotalRefund; 
     } 
    } 

    public decimal TotalDiscounts { 
     get { 
      return ((SubTotal * DiscountPercentage)/100) + DiscountAbsolute; 
     } 
    } 

    public decimal TotalSurcharges { 
     get { 
      return ((SubTotal * SurchargePercentage)/100); 
     } 
    } 

    [DisplayFormat(DataFormatString="{0:C}", ApplyFormatInEditMode = false)] 
    public decimal Total { 
     get { 
      return SubTotal - TotalDiscounts + TotalSurcharges; 
     } 
    } 

    public decimal TotalTax { 
     get { 
      return (TaxEnabled) ? OrderDetails.Sum(t => t.Taxes): 0; 
     } 
    } 

    public decimal SubTotal { 
     get { 
      return OrderDetails.Sum(o => o.Total) + TotalTax; 
     } 
    } 

    public decimal DiscountOffers { 
     get { 
      return OrderDetails.Sum(o => o.DiscountOffers); 
     } 
    } 

    public bool HasOffers { 
     get { 
      return DiscountOffers > 0; 
     } 
    } 

    public decimal SurchargePercentage { 
     get { 
      return OrderSurcharges.Sum(o => o.ChargePercentage); 
     } 
    } 

    public decimal DiscountPercentage { 
     get { 
      return OrderDiscounts.Where(o => o.Type == (int)DiscountType.Percentage).Sum(o => o.Value); 
     } 
    } 

    public decimal DiscountAbsolute 
    { 
     get 
     { 
      return OrderDiscounts.Where(o => o.Type == (int)DiscountType.Absolute).Sum(o => o.Value); 
     } 
    } 
} 

Я динамически вычислить сумму заказа, так что я всегда нужен OrderDetail * загружено от начала, чтобы избежать несколько запросов к БД, когда presentig списка 1000 заказов, например, таким образом я внедрил этот метод в моем родовом хранилище:.

public virtual IQueryable<T> GetAllIncluding(params Expression<Func<T, object>>[] includeProperties) 
    { 
     IQueryable<T> query = Fetch(); 

     foreach (var includeProperty in includeProperties) 
     { 
      query = query.Include(includeProperty); 
     } 

     return query; 
    } 

И я называю это сформировать свой код так:

private IEnumerable<Order> GetAllOrders() 
    { 
     return unitOfWork.OrderRepository.GetAllIncluding(
      o => o.OrderDiscounts, 
      o => o.OrderPayments, 
      o => o.OrderSurcharges, 
      o => o.OrderStates, 
      o => o.OrderRefunds, 
      o => o.OrderDetails, 
      o => o.OrderDetails.Select(d => d.OrderDetailDiscounts), 
      o => o.OrderDetails.Select(d => d.OrderDetailOffers), 
      o => o.User, 
      o => o.Employee, 
      o => o.Store, 
      o => o.TerminalSession); 
    } 

Ok .. он работает .. проблема, когда я должен запросить другие сложные объекты с этим, я Пользователь Entity которым состоит других дочерних организаций, например:

  • Пользователь
  • UserPoint
  • UserState
  • ...

Есть ли способ, чтобы инструктировать EF, чтобы загрузить группу лиц в целом, так что я могу запросить с помощью заказов и пользователей полностью загружен в aviod, ударяя по db при запросе большого количества записей (я не хочу отключать ленивую загрузку)

+0

Не можете ли вы просто добавить: 'o => o.User.GetAllIncluding (o => u.UserPoint, u => u.UserState, ...)'? –

+0

Да, проблема - это запрос с участием пользователя. * И Order. * Например: неуплаченные заказы от активных пользователей с менее 100 точками. – Marc

+0

Для меня похоже, что вы не должны пытаться составить один размер, соответствующий всем запросам. Вам когда-нибудь понадобится _all_, это включает в себя один случай использования? Я думаю (но, может быть, и ошибаюсь), вы должны использовать более индивидуальные запросы с (далекими) минусами и, возможно, иногда присоединяться. Если вы _really_ хотите, вы можете предварительно загрузить что-нибудь. Для этого может потребоваться запрос или два, но EF будет любезно фиксировать отношения. Но опять же, я думаю, вы запрашиваете много данных. –

ответ

0
context.Entity.Include("ChildEntity"); 

или

context.Entity.Include(x => x.ChildEntity); 

, если вам нужно больше вложенных объекты

context.Entity.Include(x => x.ChildEntity.Select(c => c.ChildChildEntity)); 

иметь в виду, что лямбда-выражение живет на System.Data.Entity пространстве имен.

Помните, что в целом слишком много соединений хуже, чем несколько вызовов db.

Смежные вопросы