/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> protected override IClrPropertyGetter CreateGeneric <TEntity, TValue, TNonNullableEnumValue>( MemberInfo memberInfo, IPropertyBase?propertyBase) { var entityParameter = Expression.Parameter(typeof(TEntity), "entity"); Expression readExpression; if (memberInfo.DeclaringType !.IsAssignableFrom(typeof(TEntity))) { readExpression = PropertyBase.CreateMemberAccess(propertyBase, entityParameter, memberInfo); }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> protected override IClrPropertyGetter CreateGeneric <TEntity, TValue, TNonNullableEnumValue>( MemberInfo memberInfo, IPropertyBase propertyBase) { var entityParameter = Expression.Parameter(typeof(TEntity), "entity"); Expression readExpression; if (memberInfo.DeclaringType.IsAssignableFrom(typeof(TEntity))) { readExpression = PropertyBase.CreateMemberAccess(propertyBase, entityParameter, memberInfo); } else { // This path handles properties that exist only on proxy types and so only exist if the instance is a proxy var converted = Expression.Variable(memberInfo.DeclaringType, "converted"); readExpression = Expression.Block( new[] { converted }, new List <Expression> { Expression.Assign( converted, Expression.TypeAs(entityParameter, memberInfo.DeclaringType)), Expression.Condition( Expression.ReferenceEqual(converted, Expression.Constant(null)), Expression.Default(memberInfo.GetMemberType()), PropertyBase.CreateMemberAccess(propertyBase, converted, memberInfo)) }); } var hasDefaultValueExpression = readExpression.MakeHasDefaultValue <TValue>(propertyBase); if (readExpression.Type != typeof(TValue)) { readExpression = Expression.Condition( hasDefaultValueExpression, Expression.Constant(default(TValue), typeof(TValue)), Expression.Convert(readExpression, typeof(TValue))); } return(new ClrPropertyGetter <TEntity, TValue>( Expression.Lambda <Func <TEntity, TValue> >(readExpression, entityParameter).Compile(), Expression.Lambda <Func <TEntity, bool> >(hasDefaultValueExpression, entityParameter).Compile())); }
private static Func <IUpdateEntry, TProperty> CreateCurrentValueGetter <TProperty>( IPropertyBase propertyBase, bool useStoreGeneratedValues) { var entityClrType = propertyBase.DeclaringType.ClrType; var updateParameter = Expression.Parameter(typeof(IUpdateEntry), "entry"); var entryParameter = Expression.Convert(updateParameter, typeof(InternalEntityEntry)); var shadowIndex = propertyBase.GetShadowIndex(); Expression currentValueExpression; if (shadowIndex >= 0) { currentValueExpression = Expression.Call( entryParameter, InternalEntityEntry.ReadShadowValueMethod.MakeGenericMethod(typeof(TProperty)), Expression.Constant(shadowIndex)); } else { var convertedExpression = Expression.Convert( Expression.Property(entryParameter, "Entity"), entityClrType); var memberInfo = propertyBase.GetMemberInfo(forMaterialization: false, forSet: false); currentValueExpression = PropertyBase.CreateMemberAccess(propertyBase, convertedExpression, memberInfo); if (currentValueExpression.Type != typeof(TProperty)) { currentValueExpression = Expression.Condition( currentValueExpression.MakeHasDefaultValue(propertyBase), Expression.Constant(default(TProperty), typeof(TProperty)), Expression.Convert(currentValueExpression, typeof(TProperty))); } } var storeGeneratedIndex = propertyBase.GetStoreGeneratedIndex(); if (storeGeneratedIndex >= 0) { if (useStoreGeneratedValues) { currentValueExpression = Expression.Condition( Expression.Equal( currentValueExpression, Expression.Constant(default(TProperty), typeof(TProperty))), Expression.Call( entryParameter, InternalEntityEntry.ReadStoreGeneratedValueMethod.MakeGenericMethod(typeof(TProperty)), Expression.Constant(storeGeneratedIndex)), currentValueExpression); } currentValueExpression = Expression.Condition( Expression.Equal( currentValueExpression, Expression.Constant(default(TProperty), typeof(TProperty))), Expression.Call( entryParameter, InternalEntityEntry.ReadTemporaryValueMethod.MakeGenericMethod(typeof(TProperty)), Expression.Constant(storeGeneratedIndex)), currentValueExpression); } return(Expression.Lambda <Func <IUpdateEntry, TProperty> >( currentValueExpression, updateParameter) .Compile()); }