2012-07-18 92 views
1

我想添加一個新的實體到數據庫已經使用EF來檢索其他數據實例。我希望能使用如下代碼如下:添加到實體框架投影中創建的集合

using (var db = new FundResearchContext(null)) 
{ 
    var query = from a in db.As select new 
       { 
        a = a, 
        bs = (from b in db.Bs where b.AnId == a.AnotherId select b) 
       }; 

    var listOfAsAndRelatedBs = query.ToList(); 
    listOfAsAndRelatedBs[0].bs.Add(new B()); 
    db.SaveChanges(); 
} 

雖然bs集合中的對象進行跟蹤,並將其保存更改後,我不能添加新項目的收集,因爲它是IQueryable類型。我意識到在這樣一個簡單的例子中,我可以將屬性放在A和B上以表示它們通過外鍵鏈接,但是這種方法在我的真實生活場景中不可行。那麼是否有一種替代語法可以使bs本身成爲一個跟蹤對象,我可以添加新的B對象並讓它們保持不變?或者我必須使用db.Bs.Add(new B())手動執行所有操作嗎?

回答

1

如果您A類有一個Bs收集就可以了,你可以說:

var query = from a in db.As select new 
      { 
       a = a, 
       bs = a.Bs 
      }; 

這有一個不錯的急切加載效果,因爲當這個查詢是馬時,所有的B s爲每個A加載和附加terialized。您應該可以將對象添加到其中一個結果的bs屬性或a.Bs屬性中。

如果你沒有在你的實體類之間建立這種關係,你將無法做到這一點,並且你會被直接添加到db.Bs。當然,你可以創建一個快捷方式的排序對象,以促進這一點:

public class DTO {public A a{get;set;} public IObjectSet<B> allBs {get;set;} } 

var list = (from a in db.As 
      select new DTO 
      { 
       a = a, 
      }).ToList(); 
foreach(var a in list) 
{ 
    a.allBs = db.Bs; 
} 

你不必訪問上下文這種方式直接將項目添加到Bs

+1

您是對的,我沒有'Bs'集合在'A'上,我可以用作導航屬性。好像我需要直接添加到'db.Bs'並跟蹤我添加到不同列表中的對象,而不是匿名投影類中的'bs'屬性。 – 2012-07-18 21:16:16

0

如果你打電話ToList()在匿名對象設置bs時,那麼bs應該是類型List<B>

using (var db = new FundResearchContext(null)) 
{ 
    var query = from a in db.As select new 
       { 
        // ... 
        bs = (from b in db.Bs 
          where b.AnId == a.AnotherId 
          select b) 
         .ToList() 
       }; 
    // ... 
} 
+2

LINQ to Entities將不允許對像這樣的查詢內的.ToList()調用。 – StriplingWarrior 2012-07-18 20:53:27

+0

恐怕我已經嘗試過了。雖然編譯器對此感到滿意,但當它執行時,我得到一個System.NotSupportedException異常,其中包含消息「LINQ to Entities does not recognized the method ...」 – 2012-07-18 20:58:10