public virtual Expression CreateMaterializeExpression( IEntityType entityType, Expression valueReaderExpression, int[] indexMap = null) { Check.NotNull(entityType, nameof(entityType)); Check.NotNull(valueReaderExpression, nameof(valueReaderExpression)); var materializer = entityType as IEntityMaterializer; if (materializer != null) { return(Expression.Call( Expression.Constant(materializer), ((Func <IValueReader, object>)materializer.CreateEntity).GetMethodInfo(), valueReaderExpression)); } if (!entityType.HasClrType()) { throw new InvalidOperationException(Strings.NoClrType(entityType.Name)); } if (entityType.IsAbstract) { throw new InvalidOperationException(Strings.CannotMaterializeAbstractType(entityType)); } var instanceVariable = Expression.Variable(entityType.ClrType, "instance"); var blockExpressions = new List <Expression> { Expression.Assign( instanceVariable, Expression.New(entityType.ClrType.GetDeclaredConstructor(null))) }; blockExpressions.AddRange( from mapping in _memberMapper.MapPropertiesToMembers(entityType) let propertyInfo = mapping.Item2 as PropertyInfo let targetMember = propertyInfo != null ? Expression.Property(instanceVariable, propertyInfo) : Expression.Field(instanceVariable, (FieldInfo)mapping.Item2) select Expression.Assign( targetMember, CreateReadValueExpression( valueReaderExpression, targetMember.Type, indexMap?[mapping.Item1.Index] ?? mapping.Item1.Index))); blockExpressions.Add(instanceVariable); return(Expression.Block(new[] { instanceVariable }, blockExpressions)); }
/// <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 virtual Expression CreateMaterializeExpression( IEntityType entityType, Expression valueBufferExpression, int[] indexMap = null) { // ReSharper disable once SuspiciousTypeConversion.Global var materializer = entityType as IEntityMaterializer; if (materializer != null) { return(Expression.Call( Expression.Constant(materializer), ((Func <ValueBuffer, object>)materializer.CreateEntity).GetMethodInfo(), valueBufferExpression)); } if (!entityType.HasClrType()) { throw new InvalidOperationException(CoreStrings.NoClrType(entityType.Name)); } if (entityType.IsAbstract()) { throw new InvalidOperationException(CoreStrings.CannotMaterializeAbstractType(entityType)); } var constructorInfo = entityType.ClrType.GetDeclaredConstructor(null); if (constructorInfo == null) { throw new InvalidOperationException(CoreStrings.NoParameterlessConstructor(entityType.DisplayName())); } var instanceVariable = Expression.Variable(entityType.ClrType, "instance"); var blockExpressions = new List <Expression> { Expression.Assign( instanceVariable, Expression.New(constructorInfo)) }; blockExpressions.AddRange( from mapping in _memberMapper.MapPropertiesToMembers(entityType) let propertyInfo = mapping.Item2 as PropertyInfo let targetMember = propertyInfo != null ? Expression.Property(instanceVariable, propertyInfo) : Expression.Field(instanceVariable, (FieldInfo)mapping.Item2) select Expression.Assign( targetMember, CreateReadValueExpression( valueBufferExpression, targetMember.Type, indexMap?[mapping.Item1.GetIndex()] ?? mapping.Item1.GetIndex()))); blockExpressions.Add(instanceVariable); return(Expression.Block(new[] { instanceVariable }, blockExpressions)); }