Skip to content

Commit c1e99c1

Browse files
Default srid (#43)
* Fix tests. * Drop table. * another fix. * Fix tests * Default SRID.
1 parent 9dd8ba0 commit c1e99c1

12 files changed

Lines changed: 111 additions & 51 deletions

File tree

src/PhenX.EntityFrameworkCore.BulkInsert.MySql/MySqlBulkInsertProvider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ CancellationToken ctk
7171
sourceOrdinal++;
7272
}
7373

74-
var dataReader = new EnumerableDataReader<T>(entities, properties, options.Converters);
74+
var dataReader = new EnumerableDataReader<T>(entities, properties, options);
7575

7676
if (sync)
7777
{

src/PhenX.EntityFrameworkCore.BulkInsert.MySql/MySqlGeometryConverter.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
using MySqlConnector;
1+
using MySqlConnector;
22

33
using NetTopologySuite.Geometries;
44

55
using PhenX.EntityFrameworkCore.BulkInsert.Abstractions;
6+
using PhenX.EntityFrameworkCore.BulkInsert.Options;
67

78
namespace PhenX.EntityFrameworkCore.BulkInsert.MySql;
89

@@ -14,11 +15,11 @@ private MySqlGeometryConverter()
1415
{
1516
}
1617

17-
public bool TryConvertValue(object source, out object result)
18+
public bool TryConvertValue(object source, BulkInsertOptions options, out object result)
1819
{
1920
if (source is Geometry geometry)
2021
{
21-
result = MySqlGeometry.FromWkb(geometry.SRID, geometry.ToBinary());
22+
result = MySqlGeometry.FromWkb(options.SRID, geometry.ToBinary());
2223
return true;
2324
}
2425

src/PhenX.EntityFrameworkCore.BulkInsert.PostgreSql/PostgreSqlBulkInsertProvider.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,6 @@ protected override async Task BulkInsert<T>(
5757
? connection.BeginBinaryImport(command)
5858
: await connection.BeginBinaryImportAsync(command, ctk);
5959

60-
var bulkValueConverters = options.Converters;
61-
6260
// The type mapping can be null for obvious types like string.
6361
var columnTypes = columns.Select(c => GetPostgreSqlType(c, options)).ToArray();
6462

@@ -76,7 +74,7 @@ protected override async Task BulkInsert<T>(
7674

7775
for (var columnIndex = 0; columnIndex < columns.Count; columnIndex++)
7876
{
79-
var value = columns[columnIndex].GetValue(entity, bulkValueConverters);
77+
var value = columns[columnIndex].GetValue(entity, options);
8078

8179
// Get the actual type, so that the writer can do the conversation to the target type automatically.
8280
var type = columnTypes[columnIndex];

src/PhenX.EntityFrameworkCore.BulkInsert.PostgreSql/PostgreSqlGeometryConverter.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
using Microsoft.EntityFrameworkCore.Metadata;
1+
using Microsoft.EntityFrameworkCore.Metadata;
22

33
using NetTopologySuite.Geometries;
44

55
using NpgsqlTypes;
66

77
using PhenX.EntityFrameworkCore.BulkInsert.Abstractions;
8+
using PhenX.EntityFrameworkCore.BulkInsert.Options;
89

910
namespace PhenX.EntityFrameworkCore.BulkInsert.PostgreSql;
1011

@@ -16,10 +17,16 @@ private PostgreSqlGeometryConverter()
1617
{
1718
}
1819

19-
public bool TryConvertValue(object source, out object result)
20+
public bool TryConvertValue(object source, BulkInsertOptions options, out object result)
2021
{
2122
if (source is Geometry geometry)
2223
{
24+
if (geometry.SRID != options.SRID)
25+
{
26+
geometry = geometry.Copy();
27+
geometry.SRID = options.SRID;
28+
}
29+
2330
result = geometry.ToBinary();
2431
return true;
2532
}

src/PhenX.EntityFrameworkCore.BulkInsert.SqlServer/SqlServerBulkInsertProvider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ protected override async Task BulkInsert<T>(
5151
bulkCopy.ColumnMappings.Add(column.PropertyName, column.ColumnName);
5252
}
5353

54-
var dataReader = new EnumerableDataReader<T>(entities, columns, options.Converters);
54+
var dataReader = new EnumerableDataReader<T>(entities, columns, options);
5555

5656
if (sync)
5757
{

src/PhenX.EntityFrameworkCore.BulkInsert.SqlServer/SqlServerGeometryConverter.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
using System.Data.SqlTypes;
1+
using System.Data.SqlTypes;
22

33
using Microsoft.SqlServer.Types;
44

55
using NetTopologySuite.Geometries;
66

77
using PhenX.EntityFrameworkCore.BulkInsert.Abstractions;
8+
using PhenX.EntityFrameworkCore.BulkInsert.Options;
89

910
namespace PhenX.EntityFrameworkCore.BulkInsert.SqlServer;
1011

@@ -16,12 +17,12 @@ private SqlServerGeometryConverter()
1617
{
1718
}
1819

19-
public bool TryConvertValue(object source, out object result)
20+
public bool TryConvertValue(object source, BulkInsertOptions options, out object result)
2021
{
2122
if (source is Geometry geometry)
2223
{
2324
var reversed = Reverse(geometry);
24-
result = SqlGeometry.STGeomFromWKB(new SqlBytes(reversed.AsBinary()), geometry.SRID);
25+
result = SqlGeometry.STGeomFromWKB(new SqlBytes(reversed.AsBinary()), options.SRID);
2526
return true;
2627
}
2728

src/PhenX.EntityFrameworkCore.BulkInsert.Sqlite/SqliteBulkInsertProvider.cs

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -144,37 +144,48 @@ CancellationToken ctk
144144
var columnList = tableInfo.GetColumns(options.CopyGeneratedColumns);
145145
var columnTypes = columnList.Select(GetSqliteType).ToArray();
146146

147-
await using var insertCommand =
148-
GetInsertCommand(
149-
context,
150-
tableName,
151-
columnList,
152-
columnTypes,
153-
sb,
154-
batchSize);
155-
156-
foreach (var chunk in entities.Chunk(batchSize))
147+
DbCommand? insertCommand = null;
148+
try
157149
{
158-
// Full chunks
159-
if (chunk.Length == batchSize)
150+
foreach (var chunk in entities.Chunk(batchSize))
160151
{
161-
FillValues(chunk, insertCommand.Parameters, columns);
162-
await ExecuteCommand(sync, insertCommand, ctk);
152+
// Full chunks
153+
if (chunk.Length == batchSize)
154+
{
155+
insertCommand ??=
156+
GetInsertCommand(
157+
context,
158+
tableName,
159+
columnList,
160+
columnTypes,
161+
sb,
162+
batchSize);
163+
164+
FillValues(chunk, insertCommand.Parameters, columns, options);
165+
await ExecuteCommand(sync, insertCommand, ctk);
166+
}
167+
// Last chunk
168+
else
169+
{
170+
await using var partialInsertCommand =
171+
GetInsertCommand(
172+
context,
173+
tableName,
174+
columnList,
175+
columnTypes,
176+
sb,
177+
chunk.Length);
178+
179+
FillValues(chunk, partialInsertCommand.Parameters, columns, options);
180+
await ExecuteCommand(sync, partialInsertCommand, ctk);
181+
}
163182
}
164-
// Last chunk
165-
else
183+
}
184+
finally
185+
{
186+
if (insertCommand != null)
166187
{
167-
await using var partialInsertCommand =
168-
GetInsertCommand(
169-
context,
170-
tableName,
171-
columnList,
172-
columnTypes,
173-
sb,
174-
chunk.Length);
175-
176-
FillValues(chunk, partialInsertCommand.Parameters, columns);
177-
await ExecuteCommand(sync, partialInsertCommand, ctk);
188+
await insertCommand.DisposeAsync();
178189
}
179190
}
180191
}
@@ -192,7 +203,11 @@ private static async Task ExecuteCommand(bool sync, DbCommand insertCommand, Can
192203
}
193204
}
194205

195-
private static void FillValues<T>(T[] chunk, DbParameterCollection parameters, IReadOnlyList<ColumnMetadata> columns) where T : class
206+
private static void FillValues<T>(
207+
T[] chunk,
208+
DbParameterCollection parameters,
209+
IReadOnlyList<ColumnMetadata> columns,
210+
BulkInsertOptions options) where T : class
196211
{
197212
var p = 0;
198213

@@ -203,7 +218,7 @@ private static void FillValues<T>(T[] chunk, DbParameterCollection parameters, I
203218
for (var columnIndex = 0; columnIndex < columns.Count; columnIndex++)
204219
{
205220
var column = columns[columnIndex];
206-
var value = column.GetValue(entity, null);
221+
var value = column.GetValue(entity, options);
207222
parameters[p].Value = value;
208223
p++;
209224
}

src/PhenX.EntityFrameworkCore.BulkInsert/Abstractions/IBulkValueConverter.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace PhenX.EntityFrameworkCore.BulkInsert.Abstractions;
1+
using PhenX.EntityFrameworkCore.BulkInsert.Options;
2+
3+
namespace PhenX.EntityFrameworkCore.BulkInsert.Abstractions;
24

35
/// <summary>
46
/// Provide an interface to control how objects are written.
@@ -10,6 +12,7 @@ public interface IBulkValueConverter
1012
/// </summary>
1113
/// <param name="source">The source object.</param>
1214
/// <param name="result">The result type.</param>
15+
/// <param name="options">The options.</param>
1316
/// <returns>Indicates if an object should be written.</returns>
14-
bool TryConvertValue(object source, out object result);
17+
bool TryConvertValue(object source, BulkInsertOptions options, out object result);
1518
}

src/PhenX.EntityFrameworkCore.BulkInsert/EnumerableDataReader.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@
22

33
using PhenX.EntityFrameworkCore.BulkInsert.Abstractions;
44
using PhenX.EntityFrameworkCore.BulkInsert.Metadata;
5+
using PhenX.EntityFrameworkCore.BulkInsert.Options;
56

67
namespace PhenX.EntityFrameworkCore.BulkInsert;
78

8-
internal sealed class EnumerableDataReader<T>(IEnumerable<T> rows, IReadOnlyList<ColumnMetadata> columns, List<IBulkValueConverter>? converters) : IDataReader
9+
internal sealed class EnumerableDataReader<T>(
10+
IEnumerable<T> rows,
11+
IReadOnlyList<ColumnMetadata> columns,
12+
BulkInsertOptions options) : IDataReader
913
{
1014
private readonly IEnumerator<T> _enumerator = rows.GetEnumerator();
1115
private readonly Dictionary<string, int> _ordinalMap =
@@ -24,7 +28,7 @@ public object GetValue(int i)
2428
return DBNull.Value;
2529
}
2630

27-
return columns[i].GetValue(current, converters)!;
31+
return columns[i].GetValue(current, options)!;
2832
}
2933

3034
public int GetValues(object[] values)
@@ -37,7 +41,7 @@ public int GetValues(object[] values)
3741

3842
for (var i = 0; i < columns.Count; i++)
3943
{
40-
values[i] = columns[i].GetValue(current, converters)!;
44+
values[i] = columns[i].GetValue(current, options)!;
4145
}
4246

4347
return columns.Count;

src/PhenX.EntityFrameworkCore.BulkInsert/Metadata/ColumnMetadata.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using PhenX.EntityFrameworkCore.BulkInsert.Abstractions;
55
using PhenX.EntityFrameworkCore.BulkInsert.Dialect;
6+
using PhenX.EntityFrameworkCore.BulkInsert.Options;
67

78
namespace PhenX.EntityFrameworkCore.BulkInsert.Metadata;
89

@@ -24,15 +25,15 @@ internal sealed class ColumnMetadata(IProperty property, SqlDialectBuilder dial
2425

2526
public bool IsGenerated { get; } = property.ValueGenerated == ValueGenerated.OnAdd;
2627

27-
public object? GetValue(object entity, List<IBulkValueConverter>? converters)
28+
public object? GetValue(object entity, BulkInsertOptions options)
2829
{
2930
var result = _getter(entity);
3031

31-
if (converters != null && result != null)
32+
if (options.Converters != null && result != null)
3233
{
33-
foreach (var converter in converters)
34+
foreach (var converter in options.Converters)
3435
{
35-
if (converter.TryConvertValue(result, out var temp))
36+
if (converter.TryConvertValue(result, options, out var temp))
3637
{
3738
result = temp;
3839
break;

0 commit comments

Comments
 (0)