entity frameworkDbEntityEntry.Property方法是否使用reflection?

这个问题是关于这段代码的:

entityEntry.Property("WhateverProperty").CurrentValue = 1; 

我昨天回答了这个问题 ,如果你在问题的评论中注意到了(不是答案),其中一名成员@gertarnold说:

entityEntry.Property(“InsertedBy”)不使用reflection,它读取EF元数据。

当然,它使用EF元数据来确定实体是否具有该属性,但我非常确定在某个地方,他们必须使用reflection来设置属性

我试着在这里 , 这里和这里查看源代码(第484行)然后加油。

所以问题是

  1. 它是否使用reflection?
  2. 如果没有,那么财产如何设定呢?

它不使用reflection(reflection是在创建元数据模型时完成的),但是一次是从编译的动态表达式构建和缓存的委托。

执行实际属性集的代码在这里 :

 internal static void SetValue(EdmProperty property, object target, object value) { var setter = GetSetterDelegateForProperty(property); setter(target, value); } 

并构建表达式并编译委托就在这里 。

基本上它创建,缓存和使用这样的东西:

 Action setter = (target, value) => ((TEntity)target).Property = (TValue)value; 

EntitEntry.CurrentValue最终通过调用一次构建的编译表达式树(构建实体模型, 然后使用reflection)并缓存为Action来在EdmProperty设置属性值:

 //  // cached dynamic method to set a CLR property value on a CLR instance //  internal Action ValueSetter { get { return _memberSetter; } set { DebugCheck.NotNull(value); // It doesn't matter which delegate wins, but only one should be jitted Interlocked.CompareExchange(ref _memberSetter, value, null); } } 

使用此方法设置属性大约比直接设置属性慢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命名空间和教程甚至没有提到实体内访问属性的任何成本这样,所以在我与微软的谦虚经验我觉得这个片段没有有反思的代价。