/// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        public override Expression BindToParameter(ParameterBindingInfo bindingInfo)
        {
            var parameters = Method.GetParameters().Select(
                (p, i) => Expression.Parameter(p.ParameterType, "param" + i)).ToArray();

            var serviceVariable  = Expression.Variable(ServiceType, "service");
            var delegateVariable = Expression.Variable(ParameterType, "delegate");

            return(Expression.Block(
                       new[] { serviceVariable, delegateVariable },
                       new List <Expression>
            {
                Expression.Assign(
                    serviceVariable,
                    base.BindToParameter(bindingInfo)),
                Expression.Assign(
                    delegateVariable,
                    Expression.Condition(
                        Expression.ReferenceEqual(serviceVariable, Expression.Constant(null)),
                        Expression.Constant(null, ParameterType),
                        Expression.Lambda(
                            Expression.Call(
                                serviceVariable,
                                Method,
                                parameters),
                            parameters))),
                delegateVariable
            }));
        }
        /// <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 override Expression BindToParameter(ParameterBindingInfo bindingInfo)
        {
            var property = ConsumedProperties[0];

            return(Expression.Call(
                       EntityMaterializerSource.TryReadValueMethod.MakeGenericMethod(property.ClrType),
                       Expression.Call(bindingInfo.MaterializationContextExpression, MaterializationContext.GetValueBufferMethod),
                       Expression.Constant(bindingInfo.GetValueBufferIndex(property))));
        }
Exemple #3
0
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        public override Expression BindToParameter(ParameterBindingInfo bindingInfo)
        => Expression.NewArrayInit(
            typeof(object),
            _bindings.Select(
                b =>
        {
            var expression = b.BindToParameter(bindingInfo);

            if (expression.Type.GetTypeInfo().IsValueType)
            {
                expression = Expression.Convert(expression, typeof(object));
            }

            return(expression);
        }));
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        public override Expression CreateConstructorExpression(ParameterBindingInfo bindingInfo)
        {
            var arguments = ParameterBindings.Select(b => b.BindToParameter(bindingInfo));

            Expression expression
                = _factoryInstance == null
                    ? Expression.Call(
                      _factoryMethod,
                      arguments)
                    : Expression.Call(
                      Expression.Constant(_factoryInstance),
                      _factoryMethod,
                      arguments);

            if (_factoryMethod.ReturnType != RuntimeType)
            {
                expression = Expression.Convert(expression, RuntimeType);
            }

            return(expression);
        }
Exemple #5
0
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        public override Expression BindToParameter(ParameterBindingInfo bindingInfo)
        {
            var parameters = Method.GetParameters().Select(
                (p, i) => Expression.Parameter(p.ParameterType, "param" + i)).ToArray();

            var serviceVariable = Expression.Variable(ServiceType, "service");

            return(Expression.Block(
                       new[] { serviceVariable },
                       new List <Expression>
            {
                Expression.Assign(
                    serviceVariable,
                    base.BindToParameter(bindingInfo)),
                Expression.Lambda(
                    Expression.Call(
                        serviceVariable,
                        Method,
                        parameters),
                    parameters)
            }));
        }
Exemple #6
0
 /// <summary>
 ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
 ///     directly from your code. This API may change or be removed in future releases.
 /// </summary>
 public override Expression BindToParameter(ParameterBindingInfo bindingInfo)
 => Expression.Call(
     EntityMaterializerSource.TryReadValueMethod.MakeGenericMethod(ConsumedProperty.ClrType),
     bindingInfo.ValueBufferExpression,
     Expression.Constant(bindingInfo.GetValueBufferIndex(ConsumedProperty)),
     Expression.Constant(ConsumedProperty, typeof(IPropertyBase)));
Exemple #7
0
 /// <summary>
 ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
 ///     directly from your code. This API may change or be removed in future releases.
 /// </summary>
 public override Expression BindToParameter(ParameterBindingInfo bindingInfo)
 => BindToParameter(
     bindingInfo.MaterializationContextExpression,
     Expression.Constant(bindingInfo.EntityType),
     null);
Exemple #8
0
 /// <summary>
 ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
 ///     directly from your code. This API may change or be removed in future releases.
 /// </summary>
 public override Expression CreateConstructorExpression(ParameterBindingInfo bindingInfo)
 => Expression.New(
     Constructor,
     ParameterBindings.Select(b => b.BindToParameter(bindingInfo)));
        /// <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));
        }
Exemple #10
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 abstract Expression BindToParameter(ParameterBindingInfo bindingInfo);
Exemple #11
0
 /// <summary>
 ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
 ///     directly from your code. This API may change or be removed in future releases.
 /// </summary>
 public override Expression BindToParameter(ParameterBindingInfo bindingInfo)
 => Expression.Constant(bindingInfo.EnityType, typeof(IEntityType));
Exemple #12
0
 /// <summary>
 ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
 ///     directly from your code. This API may change or be removed in future releases.
 /// </summary>
 public abstract Expression CreateConstructorExpression(ParameterBindingInfo bindingInfo);
Exemple #13
0
 /// <summary>
 ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
 ///     directly from your code. This API may change or be removed in future releases.
 /// </summary>
 public override Expression BindToParameter(ParameterBindingInfo bindingInfo)
 => Expression.Call(
     _getServiceMethod.MakeGenericMethod(ServiceType),
     Expression.Convert(bindingInfo.ContextExpression, typeof(IInfrastructure <IServiceProvider>)));
 /// <summary>
 ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
 ///     directly from your code. This API may change or be removed in future releases.
 /// </summary>
 public override Expression BindToParameter(ParameterBindingInfo bindingInfo)
 => Expression.TypeAs(bindingInfo.ContextExpression, ContextType);