实体框架跟踪的开销是多少?

时间:2011-11-24 13:02:25

标签: entity-framework entity-framework-4.1

我刚刚与同事谈论实体框架变更跟踪。我们最终发现我的上下文界面应该有

IDBSet<MyPoco> MyThings { get; }

而不是

IQueryable<MyPoco> MyThings { get; }

并且我的POCO也应将其所有属性都设为virtual

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

如果我的POCO属性不是virtual而我的上下文界面使用的是IQueryable<>而不是IDbSet<>,我就不会得到任何内容。

在这个例子中,我只是查询数据库,但将来会想要通过Entity Framework更新数据库。

所以,为了让我的生活变得更轻松,当我来看这个代码作为参考时,在我永远不会使用跟踪信息/代理时会不会有任何性能损失?

2 个答案:

答案 0 :(得分:3)

在EF中加强实体会有性能损失。当您使用实体框架查询时,EF将保留从数据库加载的值的副本。此外,单个Context实例仅跟踪实体的单个实例。因此,EF必须在创建实例之前检查它是否已经拥有该实体的副本(即,将在幕后进行大量比较)。

如果你不需要它,请避免使用它。你可以这样做。

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

Stages of Query Execution上的MSDN页面详细说明了与查询执行的每个步骤相关的成本。

编辑:

您不应公开IDBSet<MyPoco> MyThings,因为这会告诉消费者您的API可以在您打算查询数据时添加,更新和删除您的实体。

答案 1 :(得分:2)

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