2011-11-30 22 views
6

Ben bu basitleştirilmiş EF oluşturulan varlıkları varsayın Navigasyon Mülkiyet Dahil üzerinde Seçici Durumu ...Varlık Framework -

public class PurchaseOrder 
{ 
    public int POID {get;set;} 
    public int OrderID {get;set;} 
    public int VendorID {get;set;} 
    public IEnumerable<Order> Orders {get;set;} 
} 

public class Order 
{ 
    public int OrderID {get;set;} 
    public decimal Price {get;set;} 
    public IEnumerable<Item> Items {get;set;} 
} 

public class Item 
{ 
    public int OrderID {get; set;} 
    public string SKU {get;set;} 
    public int VendorID {get;set;} 
    public Order Order {get;set;} 
} 

İş Mantığı:

için, bir tane birden fazla PO olabilir bir sipariş Siparişteki her bir farklı satıcı (satıcılar Öğe düzeyinde belirlenir).

Çocuk Varlıklarını Nasıl Seçebilirim?

PO'ları sorgularken, Sipariş ve Öğe için otomatik olarak çocuk girişleri eklemek istiyorum.

Ben

Context.PurchaseOrders.Include("Orders.Items"); 

Bu Ben sadece Öğe varlıkları olan VendorID ait VendorID maçları dahil etmek istediğiniz, iş ve arka ilgili varlıkları çeker, ama yok ...) (Dahil kullanarak, bunu gerçekleştirmek PurchaseOrder varlığı.

Geleneksel SQL ile, bunu JOIN koşuluna dahil ederim, ancak EF bunları dahili olarak oluşturur.

LINQ sihrini, varlıklar arasında JOIN'leri manuel olarak oluşturmadan, durumu uygulamak için EF'yi kullanabilir miyim?

cevap

2

Belirli bir koşulla eşleşen belirli alt öğeleri seçici olarak seçemezsiniz. Yapabileceğiniz en iyi şey, ilgili siparişleri kendiniz manuel olarak filtrelemek.

public class PurchaseOrder 
{ 
    public int POID {get;set;} 
    public int OrderID {get;set;} 
    public int VendorID {get;set;} 
    public IEnumerable<Order> Orders {get;set;} 

    public IEnumerable<Order> MatchingOrders { 
     get { 
      return this.Orders.Where(o => o.VendorId == this.VendorId); 
     } 
    } 
} 
+0

gelecekte bir özellik donanım olarak bu görmeyi umuyoruz. – ctorx

+0

@Matthew - onlar çerçeve –

+0

büyük bir ek olurdu beş yıldan fazla ve hala hiçbir şey ... hayret verici, f herhangi bir en yararlı özellik biri için kötü değil ... -.- ' – Shockwaver

3

Yapamazsınız. EF, istekli yükleme koşullarına izin vermez. Sen gibi birden fazla sorgu kullanmalıdır ya:

var pos = from p in context.PurchaseOrders.Include("Order") 
      where ... 
      select p; 
var items = from i in context.Items 
      join o in context.Orders on new { i.OrderId, i.VendorId} 
       equals new { o.OrderId, o.PurchaseOrder.VendorId } 
      where // same condition for PurchaseOrders 
      select i; 

Yoksa tek sorguda projeksiyon kullanabilirsiniz:

var data = from o in context.Orders 
      where ... 
      select new 
       { 
        Order = o, 
        PurchaseOrder = o.PurchaseOrder, 
        Items = o.Items.Where(i => i.VendorId == o.PurchaseOrder.VendorId) 
       }; 
1

Burada IQueryable-Uzantıları kullanabilirsiniz:

https://github.com/thiscode/DynamicSelectExtensions

Uzantı dinamik olarak anonim bir tür oluşturur. Bu, @ Ladislav-Mrnka tarafından tarif edildiği gibi projeksiyon için kullanılacaktır.

Sonra bunu yapabilirsiniz:

var query = query.SelectIncluding(new List<Expression<Func<T,object>>>>(){ 

//Example how to retrieve only the newest history entry 
x => x.HistoryEntries.OrderByDescending(x => x.Timestamp).Take(1), 

//Example how to order related entities 
x => x.OtherEntities.OrderBy(y => y.Something).ThenBy(y => y.SomeOtherThing), 

//Example how to retrieve entities one level deeper 
x => x.CollectionWithRelations.Select(x => x.EntityCollectionOnSecondLevel), 

//Of course you can order or subquery the deeper level 
//Here you should use SelectMany, to flatten the query 
x => x.CollectionWithRelations.SelectMany(x => x.EntityCollectionOnSecondLevel.OrderBy(y => y.Something).ThenBy(y => y.SomeOtherThing)), 

});