2011-11-24 59 views
3

我刚刚与一位同事讨论Entity Framework更改跟踪。我们终于想通了,我的上下文接口应该有实体框架跟踪的开销是多少?

IDBSet<MyPoco> MyThings { get; } 

而不是

IQueryable<MyPoco> MyThings { get; } 

,我的POCO也应该有它的所有属性virtual

使用调试器,我们可以看到跟踪对象,并且结果还包含代表我的实际POCO的代理。

如果我没有我的POCO属性virtual和使用IQueryable<>代替IDbSet<>有我的上下文接口我没有得到任何的。

在这个例子中,我只查询数据库,但将来会希望通过实体框架来更新数据库。

因此,为了使我的生活在将来以这种代码作为参考时变得更加简单,在我将永远不会使用它们的情况下,跟踪信息/代理在那里有任何性能损失吗?

回答

3

在EF中存在加固实体的性能损失。当您使用实体框架进行查询时,EF将保留从数据库加载的值的副本。单个Context实例也只跟踪一个实体的单个实例。所以EF在创建实例之前必须检查它是否已经有实体的副本(即,在幕后会有很多比较)。

因此,如果你不需要它,请避免它。你可以这样做,如下所示。

IQueryable<MyPoco> MyThings { get { return db.MyThings.AsNoTracking(); } } 

关于Stages of Query Execution的MSDN页面详细列出了每个查询执行步骤的相关成本。

编辑:

你不应该让IDBSet<MyPoco> MyThings,因为它告诉你的API,你的实体可以添加,更新和删除的时候,其实你打算查询数据的消费者。

2

在声明为虚拟的模型类中导航属性,以暗示延迟加载功能,这意味着只有在需要时才需要导航属性。就实体对象而言,主要目标是将来自数据库的特定表记录加载到来自DbContext的DbSet中。在这种情况下你不能使用IQueryable。另外,它对DataContext没有任何意义。 IQueryable是一个完全不同的接口

+0

我实际上有一个接口,我编写了我的linq查询使用IQueryable <>。我在该接口的实现中也有IDBSet <>属性,这些属性作为IQueryable返回。 –

+0

感谢您澄清延迟加载功能,我没有考虑。 –