public bool TryGetValue(IPropertyBase propertyBase, out object value) { if (_values == null) { value = null; return(false); } var index = propertyBase.GetStoreGeneratedIndex(); if (index == -1) { value = null; return(false); } value = _values[index]; if (value == null) { return(false); } if (value == _nullSentinel) { value = null; } return(true); }
private static Func <InternalEntityEntry, TProperty> CreateCurrentValueGetter <TProperty>(IPropertyBase propertyBase) { var entityClrType = propertyBase.DeclaringEntityType.ClrType; var entryParameter = Expression.Parameter(typeof(InternalEntityEntry), "entry"); var shadowIndex = (propertyBase as IProperty)?.GetShadowIndex() ?? -1; var currentValueExpression = shadowIndex >= 0 ? (Expression)Expression.Call( entryParameter, InternalEntityEntry.ReadShadowValueMethod.MakeGenericMethod(typeof(TProperty)), Expression.Constant(shadowIndex)) : Expression.Property( Expression.Convert( Expression.Property(entryParameter, "Entity"), entityClrType), entityClrType.GetAnyProperty(propertyBase.Name)); var storeGeneratedIndex = propertyBase.GetStoreGeneratedIndex(); if (storeGeneratedIndex >= 0) { currentValueExpression = Expression.Call( entryParameter, InternalEntityEntry.ReadStoreGeneratedValueMethod.MakeGenericMethod(typeof(TProperty)), currentValueExpression, Expression.Constant(storeGeneratedIndex)); } return(Expression.Lambda <Func <InternalEntityEntry, TProperty> >( currentValueExpression, entryParameter) .Compile()); }
public void SetValue(IPropertyBase propertyBase, object value) { var index = propertyBase.GetStoreGeneratedIndex(); Debug.Assert(index != -1); _values[index] = value ?? _nullSentinel; }
private static Func <InternalEntityEntry, TProperty> CreateCurrentValueGetter <TProperty>( IPropertyBase propertyBase, bool useStoreGeneratedValues) { var entityClrType = propertyBase.DeclaringType.ClrType; var entryParameter = Expression.Parameter(typeof(InternalEntityEntry), "entry"); 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); currentValueExpression = Expression.MakeMemberAccess( convertedExpression, propertyBase.GetMemberInfo(forConstruction: false, forSet: false)); if (currentValueExpression.Type != typeof(TProperty)) { currentValueExpression = Expression.Convert(currentValueExpression, typeof(TProperty)); } } var storeGeneratedIndex = propertyBase.GetStoreGeneratedIndex(); if (useStoreGeneratedValues && storeGeneratedIndex >= 0) { currentValueExpression = Expression.Call( entryParameter, InternalEntityEntry.ReadStoreGeneratedValueMethod.MakeGenericMethod(typeof(TProperty)), currentValueExpression, Expression.Constant(storeGeneratedIndex)); } return(Expression.Lambda <Func <InternalEntityEntry, TProperty> >( currentValueExpression, entryParameter) .Compile()); }
public void SetValue(IPropertyBase propertyBase, object value) { var index = propertyBase.GetStoreGeneratedIndex(); Debug.Assert(index != -1); if (!((IProperty)propertyBase).IsNullable && value == null) { throw new InvalidOperationException( CoreStrings.DatabaseGeneratedNull(propertyBase.Name, propertyBase.DeclaringType.DisplayName())); } _values[index] = value ?? _nullSentinel; }
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()); }
public bool CanStoreValue(IPropertyBase propertyBase) => _values != null && propertyBase.GetStoreGeneratedIndex() != -1;
private static Func <InternalEntityEntry, TProperty> CreateCurrentValueGetter <TProperty>( IPropertyBase propertyBase, bool useStoreGeneratedValues) { var entityClrType = propertyBase.DeclaringType.ClrType; var entryParameter = Expression.Parameter(typeof(InternalEntityEntry), "entry"); 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); currentValueExpression = CreateMemberAccess( convertedExpression, propertyBase.GetMemberInfo(forMaterialization: false, forSet: false)); if (currentValueExpression.Type != typeof(TProperty)) { currentValueExpression = 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 <InternalEntityEntry, TProperty> >( currentValueExpression, entryParameter) .Compile()); Expression CreateMemberAccess(Expression parameter, MemberInfo memberInfo) { return(propertyBase?.IsIndexerProperty() == true ? Expression.MakeIndex( parameter, (PropertyInfo)memberInfo, new List <Expression>() { Expression.Constant(propertyBase.Name) }) : (Expression)Expression.MakeMemberAccess(parameter, 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 int GetPropertyIndex(IPropertyBase propertyBase) => propertyBase.GetStoreGeneratedIndex();