Beispiel #1
0
        private ExtendedNewExpression CreateNewExpression(IEntityType type, DirectConstructorBinding directConstructorBinding, BaseTableExpression table, Func <IProperty, Expression> makeColumnExpression)
        {
            var constructor     = directConstructorBinding.Constructor;
            var arguments       = new Expression[constructor.GetParameters().Length];
            var readableMembers = new MemberInfo[arguments.Length];
            var writableMembers = new MemberInfo[arguments.Length];

            for (var i = 0; i < arguments.Length; i++)
            {
                var binding = directConstructorBinding.ParameterBindings[i];

                arguments[i] = GetBindingExpression(type, binding, makeColumnExpression);

                if (binding.ConsumedProperties.ElementAtOrDefault(0) is IPropertyBase property)
                {
                    readableMembers[i] = property.GetReadableMemberInfo();
                    writableMembers[i] = property.GetWritableMemberInfo();
                }
            }

            return(new ExtendedNewExpression(constructor, arguments, readableMembers, writableMembers));
        }
Beispiel #2
0
        public static string GetStringConstructorOfDirectConstructorBinding(DirectConstructorBinding directConstructorBinding)
        {
            var sb = new StringBuilder();

            var v = directConstructorBinding.Constructor.GetType();

            if (directConstructorBinding.ParameterBindings.Count > 0)
            {
                throw new Exception("Parameterbinding not written");
            }
//            directConstructorBinding.Constructor.DeclaringType
            var    splitFullName = directConstructorBinding.Constructor.DeclaringType.FullName.Split("`");
            string typeFullName  = splitFullName.First();

            if (splitFullName.Length > 1)
            {
                typeFullName += "<string>";
            }

            sb.AppendFormat(
                "new DirectConstructorBinding(typeof({0}).GetDeclaredConstructor(null),new List<ParameterBinding>())",
                typeFullName);
            return(sb.ToString());
        }
Beispiel #3
0
        /// <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>
        public virtual Expression CreateMaterializeExpression(
            IEntityType entityType,
            string entityInstanceName,
            Expression materializationExpression,
            int[] indexMap = null)
        {
            if (!entityType.HasClrType())
            {
                throw new InvalidOperationException(CoreStrings.NoClrType(entityType.DisplayName()));
            }

            if (entityType.IsAbstract())
            {
                throw new InvalidOperationException(CoreStrings.CannotMaterializeAbstractType(entityType));
            }

            var constructorBinding = (ConstructorBinding)entityType[CoreAnnotationNames.ConstructorBinding];

            if (constructorBinding == null)
            {
                var constructorInfo = entityType.ClrType.GetDeclaredConstructor(null);

                if (constructorInfo == null)
                {
                    throw new InvalidOperationException(CoreStrings.NoParameterlessConstructor(entityType.DisplayName()));
                }

                constructorBinding = new DirectConstructorBinding(constructorInfo, Array.Empty <ParameterBinding>());
            }

            // This is to avoid breaks because this method used to expect ValueBuffer but now expects MaterializationContext
            var valueBufferExpression = materializationExpression;

            if (valueBufferExpression.Type == typeof(MaterializationContext))
            {
                valueBufferExpression = Expression.Call(materializationExpression, MaterializationContext.GetValueBufferMethod);
            }
            else
            {
                materializationExpression = Expression.New(MaterializationContext.ObsoleteConstructor, materializationExpression);
            }

            var bindingInfo = new ParameterBindingInfo(
                entityType,
                materializationExpression,
                indexMap);

            var properties = new HashSet <IPropertyBase>(
                entityType.GetServiceProperties().Cast <IPropertyBase>()
                .Concat(
                    entityType
                    .GetProperties()
                    .Where(p => !p.IsShadowProperty())));

            foreach (var consumedProperty in constructorBinding
                     .ParameterBindings
                     .SelectMany(p => p.ConsumedProperties))
            {
                properties.Remove(consumedProperty);
            }

            var constructorExpression = constructorBinding.CreateConstructorExpression(bindingInfo);

            if (properties.Count == 0)
            {
                return(constructorExpression);
            }

            var instanceVariable = Expression.Variable(constructorBinding.RuntimeType, entityInstanceName);

            var blockExpressions
                = new List <Expression>
                {
                Expression.Assign(
                    instanceVariable,
                    constructorExpression)
                };

            var indexerPropertyInfo = entityType.FindIndexerProperty();

            foreach (var property in properties)
            {
                var memberInfo = property.GetMemberInfo(forConstruction: true, forSet: true);

                var readValueExpression
                    = property is IServiceProperty serviceProperty
                        ? serviceProperty.GetParameterBinding().BindToParameter(bindingInfo)
                        : CreateReadValueExpression(
                          valueBufferExpression,
                          memberInfo.GetMemberType(),
                          indexMap?[property.GetIndex()] ?? property.GetIndex(),
                          property);

                blockExpressions.Add(
                    property.IsIndexedProperty()
                        ? Expression.Assign(
                        Expression.MakeIndex(
                            instanceVariable,
                            indexerPropertyInfo,
                            new[]
                {
                    Expression.Constant(property.Name)
                }),
                        readValueExpression)
                        : Expression.MakeMemberAccess(
                        instanceVariable,
                        memberInfo).Assign(
                        readValueExpression));
            }

            blockExpressions.Add(instanceVariable);

            return(Expression.Block(
                       new[]
            {
                instanceVariable
            }, blockExpressions));
        }