2014-05-02 208 views
0

我花了過去3個小時淘到互聯網,需要更好的想法如何實現我所需要的。我有實體的關係如下(注:關係,而不是實際域)實體框架 - 加載嵌套實體

class Person 
{ 
    int Id {get;set;} 
    string Name {Get;set;} 
    virtual DbSet<Order> Orders {get;set;} 
} 

class Order 
{ 
    int OrderId {get;set;} 
    Person Person {get;set;} 
    virtual DbSet<Item> Items {get;set;} 
} 

class Item 
{ 
    int ItemId{get;set;} 
    Order Order {get;set;} 
} 

我需要做的是從數據庫中查詢這些並將它們存儲到這又是存儲在一個字典緩存。我選擇了存儲爲字典,因爲程序需要由人名定期執行獲取項目

Dictionary<string, Item> 

這裏是我到目前爲止已經完成。

1)基本的Linq 2 SQL。問題在於字典值被創建爲代理,並且在從緩存中加載項目字典時由於ObjectContext已關閉而導致程序失敗。

using(var context = new myContext(dbFactory.Create(), contextOwnsConnection: true)) 
{ 
var itemLookup = context.Items 
      .Include(p=>p.Order.Person) 
      .AsNoTracking() 
      .GroupBy(p => p.Order.Person.Name) 
      .ToDictionary(key=>key.Key, val=> val.ToList()); 
} 

2)禁用代理創建。我得到了我從列表中選擇所需,但嵌套實體(人,順序)未設置(即Item.Order = NULL)

context.Configuration.LazyLoadingEnabled = false; 
context.Configuration.ProxyCreationEnabled = false; 
var itemLookup = context.Items 
      .Include(p=>p.Order.Person) 
      .AsNoTracking() 
      .GroupBy(p => p.Order.Person.Name) 
      .ToDictionary(key=>key.Key, val=> val.ToList()); 

我已經嘗試了一些其他的事情一樣,包括.INCLUDE(」 Order.Person「),GroupJoin(我覺得太難閱讀了)。現在,我知道我可以通過兩個其他選項來解決這個問題:

1)將三個實體加載爲字典(對每個當然都進行適當的過濾),並在代碼中設置關係。

2)使用Dapper,因爲我已經有了更多的成功。我不選擇這個的原因是我的團隊更熟悉EF的工作。

有沒有其他方法可以實現我需要使用EF?

謝謝

+0

你試過設置ProxyCreationEnabled = false;並讓lazyloadingenabled設置爲true? –

+0

在你的第二次嘗試擺脫AsNoTracking(),它會工作。 –

+0

感謝Karthik和Rand的迴應。不幸的是,兩者仍然沒有奏效。我將依賴將數據加載到字典中並在其下建立關係。 – Migg

回答

0

不幸的是,我不得不解決手動建立代碼中的對象的關係。我確信有一種方法可以讓這個問題變得不那麼痛苦,希望有人能夠爲此付出代價。

var personItemDict = new Dictionary<string, Item>(); 
var persons = context.Persons.Where(<condition>).ToDictionary(k=>k.Id, v=>v); 
var orders = context.Orders.Where(<condition>).ToDictionary(k=>k.OrderId, v=>v); 
var items = context.Items.Where(condition).ToList(); 

foreach(var item in items) 
{ 
    item.Order = orders[item.OrderId]; 
    item.Order.Person = persons[item.Order.PersonId]; 

    // Add to dictionary 
    if(false == personItemDict.ContainsKey(item.Order.Person.Name)) 
    { 
     personItemDict.Add(
      item.Order.Person.Name, 
      new List<Items>()); 
    } 

    personItemDict[item.Order.Person.Name].Add(item); 
}