public Action <MappingSchema, NpgsqlBinaryImporter, ColumnDescriptor[], TEntity> CreateBinaryImportRowWriter <TEntity>( PostgreSQLDataProvider provider, BasicSqlBuilder sqlBuilder, ColumnDescriptor[] columns, MappingSchema mappingSchema) { var generator = new ExpressionGenerator(_typeMapper); var pMapping = Expression.Parameter(typeof(MappingSchema)); var pWriterIn = Expression.Parameter(typeof(NpgsqlBinaryImporter)); var pColumns = Expression.Parameter(typeof(ColumnDescriptor[])); var pEntity = Expression.Parameter(typeof(TEntity)); var pWriter = generator.AddVariable(Expression.Parameter(_npgsqlBinaryImporterType)); generator.Assign(pWriter, Expression.Convert(ExpressionHelper.Property(pWriterIn, nameof(TypeWrapper.instance_)), _npgsqlBinaryImporterType)); generator.AddExpression(generator.MapAction((NpgsqlBinaryImporter importer) => importer.StartRow(), pWriter)); for (var i = 0; i < columns.Length; i++) { var npgsqlType = provider.GetNativeType(columns[i].DbType, true); if (npgsqlType == null) { var columnType = columns[i].DataType != DataType.Undefined ? new SqlDataType(columns[i]) : null; if (columnType == null || columnType.Type.DataType == DataType.Undefined) { columnType = mappingSchema.GetDataType(columns[i].StorageType); } var sb = new StringBuilder(); sqlBuilder.BuildTypeName(sb, columnType); npgsqlType = provider.GetNativeType(sb.ToString(), true); } if (npgsqlType == null) { throw new LinqToDBException($"Cannot guess PostgreSQL type for column {columns[i].ColumnName}. Specify type explicitly in column mapping."); } // don't use WriteNull because Write already handle both null and DBNull values properly // also use object as type parameter, as it is not important for npgsql now generator.AddExpression( Expression.Call( pWriter, "Write", new[] { typeof(object) }, //columns[idx].GetValue(mappingSchema, entity) Expression.Call(Expression.ArrayIndex(pColumns, Expression.Constant(i)), "GetValue", Array <Type> .Empty, pMapping, pEntity), Expression.Convert(Expression.Constant(npgsqlType.Value), _dbTypeType))); } var ex = Expression.Lambda <Action <MappingSchema, NpgsqlBinaryImporter, ColumnDescriptor[], TEntity> >( generator.Build(), pMapping, pWriterIn, pColumns, pEntity); return(ex.Compile()); }
public void Setup() { var typeMapper = new TypeMapper(); typeMapper.RegisterTypeWrapper <Wrapped.NpgsqlBinaryImporter>(typeof(Original.NpgsqlBinaryImporter)); typeMapper.RegisterTypeWrapper <Wrapped.NpgsqlDbType>(typeof(Original.NpgsqlDbType)); typeMapper.FinalizeMappings(); _wrappedImporter = typeMapper.Wrap <Wrapped.NpgsqlBinaryImporter>(_originalImporter); var ed = MappingSchema.GetEntityDescriptor(typeof(TestEntity)); _columns = ed.Columns.ToArray(); var generator = new ExpressionGenerator(typeMapper); var pMapping = Expression.Parameter(typeof(MappingSchema)); var pWriterIn = Expression.Parameter(typeof(Wrapped.NpgsqlBinaryImporter)); var pColumns = Expression.Parameter(typeof(ColumnDescriptor[])); var pEntity = Expression.Parameter(typeof(TestEntity)); var pWriter = generator.AddVariable(Expression.Parameter(typeof(Original.NpgsqlBinaryImporter))); generator.Assign(pWriter, Expression.Convert(Expression.PropertyOrField(pWriterIn, "instance_"), typeof(Original.NpgsqlBinaryImporter))); generator.AddExpression(generator.MapAction((Wrapped.NpgsqlBinaryImporter importer) => importer.StartRow(), pWriter)); for (var i = 0; i < _columns.Length; i++) { generator.AddExpression( Expression.Call( pWriter, "Write", new[] { typeof(object) }, Expression.Call(Expression.ArrayIndex(pColumns, Expression.Constant(i)), "GetValue", Array <Type> .Empty, pEntity), Expression.Convert(Expression.Constant(Wrapped.NpgsqlDbType.Test), typeof(Original.NpgsqlDbType)))); } _rowWriter = Expression.Lambda <Action <MappingSchema, Wrapped.NpgsqlBinaryImporter, ColumnDescriptor[], TestEntity> >( generator.Build(), pMapping, pWriterIn, pColumns, pEntity) .Compile(); }