作为实体框架代码的一些测试的一部分首先,我正在测试更改跟踪。在一个小型测试数据库中,我在一个表中有两辆车,我运行一个测试方法:
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();
我已将跟踪输出添加到TopSpeed
类的Brand
和Car
属性的getter和setter,以查看它们的访问方式。 TopSpeed
是int?
,Brand
是Brand
实体的导航属性。运行上面的代码给出了下面的输出。
Reading cars... Setting TopSpeed to 210 for ABC123. Car: Getting TopSpeed for ABC123. Setting TopSpeed to 250 for XYZ987. Car: Getting TopSpeed for XYZ987. Updating top speed of the first car... Type of car[0] is System.Data.Entity.DynamicProxies.Car_18E3E11297DC48759312BDF1C2FFEBE9F19BAE5D487CED2A9781A6CA730071EA Setting TopSpeed to 260 for ABC123. Saving changes... Car: Getting Brand for ABC123. Car: Getting Brand for XYZ987. Car: Getting TopSpeed for ABC123. Car: Getting TopSpeed for ABC123. Car: Getting TopSpeed for XYZ987. Car: Getting TopSpeed for ABC123. Car: Getting TopSpeed for ABC123. Car: Getting TopSpeed for ABC123. Car: Getting TopSpeed for ABC123. Car: Getting TopSpeed for ABC123.
对象的类型是用于更改跟踪的EF动态代理。但是,当调用SaveChanges()
时,将读取未更改的XYZ987汽车的属性。我认为更改跟踪会导致EF只读取已知更改的对象,或者我错过了什么?我还需要添加其他内容才能启用更改跟踪吗?
答案 0 :(得分:3)
即使已满足更改跟踪代理的所有要求,除非明确关闭,否则EF仍会使用自动更改跟踪:
context.Configuration.AutoDetectChangesEnabled = false;
AutoDetectChangesEnabled
上的文档令人困惑:
如果自动检测配置中的更改,则为true 启用;否则,错误。
查看ADO.NET的blog,他们正确地解释了它。
答案 1 :(得分:3)
在.NET 4上运行的EF 4.1,4.2和4.3中存在一个错误(或者说缺少优化),导致DetectChanges处理应该知道不需要更改跟踪的实体。这是因为在.NET 4上运行的EF不会跟踪是否存在任何需要更改跟踪的实体,因此每次都必须进行检查。
在.NET 4.5上运行时,这已在EF5上修复,现在很快就会推出测试版。我刚刚验证了使用.NET 4.5上的EF5,即使AutoDetectChangesEnabled设置为true,也不会在SaveChanges中调用未更改的更改跟踪代理属性的getter。
话虽如此,即使在EF 4.1-4.3上,我也不相信如果所有EF正在进行的调用是在检查实体是否是更改跟踪代理,那么似乎可能还有另一个这里的错误。
答案 2 :(得分:2)
要启用动态更改跟踪,您需要将所有标量(非导航)属性设置为虚拟。