Пример #1
0
            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());
        }
Пример #5
0
            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());
        }
Пример #7
0
 public bool CanStoreValue(IPropertyBase propertyBase)
 => _values != null &&
 propertyBase.GetStoreGeneratedIndex() != -1;
Пример #8
0
        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();