实体框架投影到类比选择 EF POCO 对象更快,为什么?
这让我很困惑。
我正在使用 EF 4.1 并将 T4 模板应用于模型以使用 POCO 和 POCO 代理(公共无参数构造函数,所有属性都是虚拟的,所有导航属性都是 ICollection)。
我有一个表,其中包含大约 110 万条记录。我正在做一些计时测试,看看检索这些数据需要多长时间,并得到了一些意想不到的结果。
此调用将在大约 21 秒内返回:
ctx.Valuations.MergeOption = MergeOption.NoTracking
var entityValuations = ctx.Valuations.OfType<Foo>().ToArray();
此调用需要 9 秒:
ctx.Valuations.MergeOption = MergeOption.NoTracking
var entityValuations = ctx.Valuations.OfType<Foo>().Select(v => new Val()
{
ID = v.ID
...
//set all properties
....
}).ToArray();
这两个语句之间的唯一区别是第一个返回 EF poco 代理,第二个将结果集投影到非代理 poco 中。这在性能时间上有如此巨大的差异!我完全不明白为什么,也想不出任何合理的理由。
有谁知道为什么第二个语句这么快?
This one confounds me.
I am using EF 4.1 and have applied a T4 template to the model to use POCO's and POCO proxies (public paramaterless ctor, all properties are virtual, all navigation properties are ICollection).
I have a table with around 1.1M records in it. I was doing some timing tests to see how long it takes to retrieve this data and got some unexpected results.
This call returns in about 21 seconds:
ctx.Valuations.MergeOption = MergeOption.NoTracking
var entityValuations = ctx.Valuations.OfType<Foo>().ToArray();
This call takes 9 seconds:
ctx.Valuations.MergeOption = MergeOption.NoTracking
var entityValuations = ctx.Valuations.OfType<Foo>().Select(v => new Val()
{
ID = v.ID
...
//set all properties
....
}).ToArray();
The only difference between these two statements is that the first returns EF poco proxies and the second projects the result set into a non-proxy poco. That is such a HUGE difference in performance time! I am completely stumped as to why and cannot come up with any legitimate reason.
Does anyone know why the second statement is so much faster?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
POCO 代理就是代理。必须为每个代理类创建一个新的代理类并将其添加到上下文中。虽然您基本上已经说过“不要在上下文中跟踪它们”,但我认为这会更快一点,但我认为您正在创建额外的 110 万个代理对象。
注:http://msdn.microsoft.com/en-us/library/ dd456853.aspx
“
您可以混合使用 POCO 实体和代理实体对象。要禁用创建代理对象,请将 ObjectContextOptions 实例上的 ProxyCreationEnabled 属性值设置为 false,该实例由 ObjectContext 上的 ContextOptions 属性返回:
“
通过 ProxyCreationEnabled 关闭上下文中的代理并查看结果是什么 - 我会收集类似的结果,这将是一个有趣的测试。
POCO proxies are just that - proxies. A new proxy class must be created for every one and added to the context. Although you have essentially said 'dont track them in the context' Id think it would be a bit faster, but I think you are creating an additional 1.1M objects that are proxies.
Note from: http://msdn.microsoft.com/en-us/library/dd456853.aspx
"
You can have a mix of POCO entities and proxy entity objects. To disable creating proxy objects, set the value of the ProxyCreationEnabled property to false on the instance of ObjectContextOptions that is returned by the ContextOptions property on the ObjectContext:
"
It would be an interesting test to turn off the proxy on the context via ProxyCreationEnabled and see what your result is - I'd gather similar.