2015-11-13 46 views
0

我有兩個實體:OrderItem以及它們之間的多對多關係。我有收到項目Id爲參數這樣的方法:更新EF中添加關聯行的行(多對多)

public void AddItems(int OrderId, int ItemId) 
     { 
      Item item = db.ItemSet.SingleOrDefault(i => i.Id == ItemId); 
      Order order = db.OrderSet.SingleOrDefault(o => o.Id == OrderId); 

      order.Items.Add(item); 
      db.SaveChanges(); 
     } 

有很多的項目集錶行的,所以第一個查詢是一個沉重的一個。有沒有一種方法可以將項目添加到訂單中,而無需先在「ItemSet」表上執行查詢?我的意思是,我可以將ItemId直接添加到Order.Items或類似的東西嗎?

+0

如果你希望能夠到的,你需要的加入表中的代碼模型!那樣你就可以對這些實體的創建進行更精細的紋理控制 –

回答

1
 Item item = new Item { ID = ItemId }; 
     Order order = new Order { ID = OrderId }; 

     db.ItemSet.Attach(item); 
     db.OrderSet.Attach(order); 

     order.Items.Add(item); 

     db.SaveChanges(); 

只要確保你有這樣的在你的Order類:

public Order() 
    { 
     Items = new List<Item>(); 
    } 

所以你沒有得到空指針異常的order.Items.Add(item);

+0

謝謝,'Attack()'像冠軍一樣工作。 –

0

所以,你可以在實體建模,因此:

public DbSet<Item> ItemSet {get;set;} 
public DbSet<Order> OrderSet {get;set;} 
public DbSet<ItemOrder> ItemOrders {get;set;} 

public class Item 
{ 
    public int Id {get;set;} 
} 

public class Order 
{ 
    public int Id {get;set;} 
} 

public class ItemOrder 
{ 
    [Key, Column(Order = 0)] 
    public int ItemId {get;set;} 

    [Key, Column(Order = 1)] 
    public int OrderId {get;set;} 
} 

所以爲了更新:

public void AddItems(int OrderId, int ItemId) 
    { 
     var itemExists = db.ItemOrders.FirstOrDefault(x => x.OrderId == OrderId && x.ItemId == ItemId); 

     if (itemExists != null) return;    

     db.ItemOrders.Add(new ItemOrder { OrderId = OrderId, ItemId = ItemId }); 

     db.SaveChanges(); 
    } 

然後你可以使用LINQ .Join()進行查詢,並且非常簡單。

爲了完整起見,OP提到導航屬性現在已經消失。所以,如果你知道OrderId,那麼你可以簡單的做:

var items = db.ItemOrders.GroupJoin(
       db.ItemSet, 
       io => io.ItemId, 
       i => i.Id, 
       (itemOrder, items) => items) 
       .ToList(); 

因此,要通過走你,GroupJoin請求的數據要加入對IQueryable/IEnumerable

第二個參數是初始數據集的字段,即ItemOrders您要加入的集合。

第三個參數是要加入的集合的字段,即ItemSet

第fouth參數基本上是Select,在那裏您會看到大約(ItemOrder itemInFirstSet, IEnumerable<Item> itemsThatAreJoined)Func簽名。

您可以將相同的邏輯應用於LINQ Join擴展。但不是itemsThatAreJoined它是itemThatIsJoined。所以區別是GroupJoin會找到匹配的多個實體,Join只會找到一個。

這是沒有辦法的詳細說明,更多的概述

+0

但是後來我失去了導航屬性,並且無法對'Order.Items'做一個foreach,例如。 –

+0

你可以,你只需要制定一個不同的查詢!一切皆有可能 –

+0

對不起,但我不明白。這比'ItemSet'表中的查詢更有效嗎?如果有很多Items,ItemOrders表中會有更多的記錄。 –