2014-05-02 207 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); 
}