2012-03-28 33 views
0

最近,我们关闭了实体框架的延迟加载和代理生成。在此之前,在我们对EF进行了新的更改之后,我们会收到整个对象图。我现在正在做的是,在提交之后,我调用存储库上的FindById方法来获取新对象(我将导航属性包含在newley创建的对象中)。我的问题是,这是创建后的标准做法,还是客户端应该负责第二次调用服务以获取新创建的对象?在使用Service和Entity Framework 4.1时保存并返回新创建的对象?

public SomeObject Create(SomeObject someObject) 
{ 
    _repository.Add(someObject); 
    _repository.UnitOfwork.Commit() 

    //this did not exist when lazy loading and proxy generation were enabled. 
    var newObject = _repository.FindById(someObject.Id); 
    return newObject; 

    //Before we would jsut return the created object because everything was loaded. 
    //return someObject 

} 

我只是想知道这是否是一个最佳实践的对象与延迟加载和代理的创建禁用创建后:在服务

保存方法。我很想知道其他开发人员如何处理这个问题。

+0

我不明白你为什么要加载你刚刚保存,而且还有在手的对象。如果'FindById'使用'Commit'使用的同一个上下文,'newObject'只会引用与'someObject'相同的对象,它仍然与上下文相连。我的猜测是你的问题与加载导航属性有关,但对我而言并不明确。 FindById是否包含所有导航属性的Include属性,这些导航属性应该取代以前的惰性加载? – Slauma 2012-03-28 13:13:11

+0

@Slauma,你对包含和导航属性是正确的。我确实想在提交后加载导航属性。 – DDiVita 2012-03-28 18:47:24

回答

2

在我们将返回创建的对象之前,因为一切都被加载了 。

我有点怀疑,这是真的。如果您致电SaveChanges EF不执行查询来加载导航属性,无论您是否使用延迟加载。例如:

假设你有订单导航参考客户并在数据库中已经使用id = 1。客户现在您创建订单(延迟加载启用):

var order = context.Orders.Create(); 
order.CustomerId = 1; 
context.Orders.Add(order); 
context.SaveChanges(); 

bool isCustomerLoaded = context.Entry(order).Reference(o => o.Customer).IsLoaded; 

isCustomerLoadedfalse - 除非客户1已经在上下文中,但随后的财产,也没有延迟加载(“关系修正”)来填充。当然,只要你访问order.Customer它会被加载由于懒加载,但后来发生的并具有无关SaveChanges

如果你的代码是一个好主意与否,取决于所使用的返回对象的方式,什么消费者的期望。通常,没有延迟加载的最接近延迟加载的替换是显式加载,因为两个加载策略执行单个查询来加载导航属性。这当然意味着你必须在消费者端引入额外的代码来加载属性,而当你使用一个属性并且在代理对象的重载属性获取器中发生查询时,延迟加载“它只是起作用”。显式加载如下所示:

context.Entry(order).Reference(o => o.Customer).Load(); 
// or for collections 
context.Entry(order).Collection(o => o.OrderItems).Load(); 

您必须在第一次访问导航属性的地方调用此函数。

如果你事先知道该对象从Create方法返回将所有需要导航属性,那么你可以加载它们与预先加载你提议的方式。但是与延迟加载相比,这肯定是数据库访问模式的一种变化:Eager加载只需要一个查询来加载整个对象图,但这是一个潜在的非常昂贵的查询,DB中有很多JOIN和许多数据回。延迟加载和显式加载会发出多个查询,但返回的数据较少的简单查询。不考虑模型细节和做测量,不可能说什么更好。

+0

你是对的,我在写这篇文章时很匆忙,所以我对缺乏细节表示歉意。凭借EF创建的代理,我可以访问相关实体。这就是我在保存更改后访问它们的原因。导航只在我请求时才加载。我提出了一个基础设施(我将分享)在提交或一般查询后包含特定实体。 – DDiVita 2012-03-28 21:40:37

+0

我更想知道其他用户是否包含(在reget期间)或在提交后特别加载实体。通过引用()。Load,我想知道这是否会更好,然后像你说的那样利用Include()。 – DDiVita 2012-03-28 21:40:56

+0

这是一篇很好的文章:http://thedatafarm.com/blog/data-access/the-cost-of-eager-loading-in-entity-framework/ – DDiVita 2012-03-28 21:44:32

相关问题