/// <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)))); }
/// <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); }
/// <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) })); }
/// <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)));
/// <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);
/// <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)); }
/// <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);
/// <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));
/// <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);
/// <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);