0

作为 Entity Framework Code First 测试的一部分,我正在测试更改跟踪。在一个小型测试数据库中,我在一个表中有两辆汽车,我对其运行测试方法:

Debug.WriteLine("Reading cars...");
var cars = context.Cars.ToArray();
Debug.WriteLine("Updating top speed of first car...");
Debug.WriteLine(string.Format("Type of car[0] is {0}", cars[0].GetType().ToString()));
cars[0].TopSpeed = 260;

Debug.WriteLine("Saving changes...");
context.SaveChanges();

我已将跟踪输出添加到类的TopSpeedBrand属性的 getter 和 setter 中,Car以查看它们是如何被访问的。TopSpeed是一个int?并且BrandBrand实体的导航属性。运行上面的代码会得到下面的输出。

读车...
将 ABC123 的 TopSpeed 设置为 210。
汽车:为 ABC123 获得 TopSpeed。
将 XYZ987 的 TopSpeed 设置为 250。
汽车:为 XYZ987 获得 TopSpeed。
正在更新第一辆车的最高速度...
汽车类型 [0] 是 System.Data.Entity.DynamicProxies.Car_18E3E11297DC48759312BDF1C2FFEBE9F19BAE5D487CED2A9781A6CA730071EA
将 ABC123 的 TopSpeed 设置为 260。
正在保存更改...
汽车:为 ABC123 获得品牌。
汽车:为 XYZ987 获得品牌。
汽车:为 ABC123 获得 TopSpeed。
汽车:为 ABC123 获得 TopSpeed。
汽车:为 XYZ987 获得 TopSpeed。
汽车:为 ABC123 获得 TopSpeed。
汽车:为 ABC123 获得 TopSpeed。
汽车:为 ABC123 获得 TopSpeed。
汽车:为 ABC123 获得 TopSpeed。
汽车:为 ABC123 获得 TopSpeed。

对象的类型是用于更改跟踪的 EF 动态代理。尽管如此,当调用SaveChanges()未更改的 XYZ987 汽车的属性时,仍会被读取。我认为更改跟踪会导致 EF 仅读取已知更改的对象,还是我遗漏了什么?我还需要添加其他内容以启用更改跟踪吗?

4

3 回答 3

3

即使满足更改跟踪代理的所有要求,EF 仍使用自动更改跟踪,除非明确关闭:

context.Configuration.AutoDetectChangesEnabled = false;

上的文档AutoDetectChangesEnabled令人困惑:

如果启用了配置更改的自动检测,则为真;否则为假。

查看 ADO.NET 的博客,他们正确地解释了它。

于 2012-02-24T09:11:40.240 回答
3

在 .NET 4 上运行的 EF 4.1、4.2 和 4.3 中存在一个错误(或者更确切地说,缺乏优化),这会导致 DetectChanges 处理应该知道不需要更改跟踪的实体。这是因为在 .NET 4 上运行的 EF 不会跟踪是否有任何实体需要更改跟踪,因此每次都必须检查。

在 .NET 4.5 上运行时,此问题已在 EF5 上得到修复,现在很快将提供 beta 版。我刚刚验证了在 .NET 4.5 上使用 EF5 时,即使 AutoDetectChangesEnabled 设置为 true,SaveChanges 中也不会调用未更改更改跟踪代理的属性的 getter。

That being said, even on EF 4.1-4.3 I don't believe that the getter should be called if all EF is doing is checking whether or not the entity is a change tracking proxy, so it seems like there might be another bug here.

于 2012-02-27T02:02:57.043 回答
2

要启用动态更改跟踪,您需要将所有标量(非导航)属性设为虚拟。

于 2012-02-23T14:44:20.850 回答