Does the Entity Framework DbEntityEntry.Property method use reflection?

This question relates to this code:

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

I answered this question yesterday, and if you noticed in the comments on the question (and not the answer), one of the @gertarnold participants said the following:

entityEntry.Property ("InsertedBy") does not use reflection, it reads EF metadata.

I'm sure it uses EF metadata to find out if the object has this property, but I'm sure somewhere where they would have to use reflection to set the property.

I tried to look at the source code here , here and here (line 484) , and then ran out of steam.

So the questions are :

  • Does this use reflection?
  • If not, how is the property set?
+4
source share
3 answers

It does not use reflection (reflection is performed during the creation of the metadata model), but once a built-in and cached delegate from a compiled dynamic expression.

The code that makes the actual set of properties is here :

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

and constructing an expression and compiling a delegate here .

It basically creates, caches, and uses something like this:

 Action<object, object> setter = (target, value) => ((TEntity)target).Property = (TValue)value; 
+5
source

EntitEntry.CurrentValue finishes setting the property value in EdmProperty , invoking the compiled expression tree constructed once (when constructing the entity model, and then using reflection) and is cached as Action :

 // <summary> // cached dynamic method to set a CLR property value on a CLR instance // </summary> internal Action<object, object> 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); } } 

Setting a property with this method is about 8 times slower than setting it directly, but still much faster than reflection, even when PropertyInfo cached. It is shown here . Summarizing:

 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 

So, as expected, EF uses the fastest method to set the value of a property in the object, which the installer must determine at run time. Faster methods require knowledge of compilation time for entity types or a third-party library.

+2
source

@CodingYoshi thank you for helping me a lot, I know that I can’t answer one of your questions, but I really understand this discussion a lot and I found an answer. I think this is true and logical after I read this msdn chapter

this means that you can access the property as a string or as an expression like this:

  string currentName1 = context.Entry(blog).Property(u => u.Name).CurrentValue; 

without mentioning the reflection or the System.Reflection namespace and the implementation, even at the top of the System.Reflection namespace and the tutorial, I don’t even mention any costs in the access properties inside the object this way, so in my humble experience with Microsoft I think this is a fragment has no reflection value.

-1
source

Source: https://habr.com/ru/post/1275821/


All Articles