entity frameworkDbEntityEntry.Property方法是否使用reflection?
这个问题是关于这段代码的:
entityEntry.Property("WhateverProperty").CurrentValue = 1;
我昨天回答了这个问题 ,如果你在问题的评论中注意到了(不是答案),其中一名成员@gertarnold说:
entityEntry.Property(“InsertedBy”)不使用reflection,它读取EF元数据。
当然,它使用EF元数据来确定实体是否具有该属性,但我非常确定在某个地方,他们必须使用reflection来设置属性 。
我试着在这里 , 这里和这里查看源代码(第484行)然后加油。
所以问题是 :
- 它是否使用reflection?
- 如果没有,那么财产如何设定呢?
它不使用reflection(reflection是在创建元数据模型时完成的),但是一次是从编译的动态表达式构建和缓存的委托。
执行实际属性集的代码在这里 :
internal static void SetValue(EdmProperty property, object target, object value) { var setter = GetSetterDelegateForProperty(property); setter(target, value); }
并构建表达式并编译委托就在这里 。
基本上它创建,缓存和使用这样的东西:
Action
EntitEntry.CurrentValue
最终通过调用一次构建的编译表达式树(构建实体模型, 然后使用reflection)并缓存为Action
来在EdmProperty
设置属性值:
// // cached dynamic method to set a CLR property value on a CLR instance // internal Action
使用此方法设置属性大约比直接设置属性慢8倍,但仍然比reflection快得多,即使缓存PropertyInfo
也是如此。 这在这里得到certificate。 总结一下:
Writing a Property ('Set') Method Mean =========================================== SetViaProperty 1.4043 ns SetViaDelegate 2.8215 ns SetViaILEmit 2.8226 ns SetViaCompiledExpressionTrees 10.7329 ns <= SetViaFastMember 36.6210 ns SetViaReflectionWithCaching 214.4321 ns SetViaReflection 287.1039 ns SetViaDelegateDynamicInvoke 922.4618 ns
因此,正如预期的那样,EF使用最快的方法在对象中设置属性值,该对象必须在运行时确定setter。 更快的方法需要实体类型或第三方库的编译时知识。
@CodingYoshi感谢你以前给我的帮助很多,我知道我可能没有资格回答你的一个问题,但我真的在讨论这个问题很多,我发现答案我认为这是真的和逻辑上我读完这一章后来自msdn
这提到你可以像字符串或表达式一样访问属性:
string currentName1 = context.Entry(blog).Property(u => u.Name).CurrentValue;
没有提到reflection或System.Reflection命名空间和实现甚至没有在System.Reflection命名空间和教程甚至没有提到实体内访问属性的任何成本这样,所以在我与微软的谦虚经验我觉得这个片段没有有反思的代价。