Skip to content

Commit ce6db20

Browse files
committed
Initial Async Support
1 parent f4fece1 commit ce6db20

5 files changed

Lines changed: 133 additions & 74 deletions

File tree

src/EntityFrameworkCore.SqlServer.SimpleBulks.Demo/Program.cs

Lines changed: 58 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -2,86 +2,80 @@
22
using EntityFrameworkCore.SqlServer.SimpleBulks.BulkInsert;
33
using EntityFrameworkCore.SqlServer.SimpleBulks.BulkMerge;
44
using EntityFrameworkCore.SqlServer.SimpleBulks.BulkUpdate;
5+
using EntityFrameworkCore.SqlServer.SimpleBulks.Demo;
56
using EntityFrameworkCore.SqlServer.SimpleBulks.Demo.Entities;
67
using Microsoft.EntityFrameworkCore;
78
using System;
89
using System.Collections.Generic;
910

10-
namespace EntityFrameworkCore.SqlServer.SimpleBulks.Demo;
1111

12-
class Program
12+
using (var dbct = new DemoDbContext())
1313
{
14-
static void Main(string[] args)
15-
{
16-
using (var dbct = new DemoDbContext())
17-
{
18-
dbct.Database.Migrate();
14+
dbct.Database.Migrate();
1915

20-
var deleteResult = dbct.BulkDelete(dbct.Set<ConfigurationEntry>().AsNoTracking(),
21-
opt =>
22-
{
23-
opt.LogTo = Console.WriteLine;
24-
});
16+
var deleteResult = dbct.BulkDelete(dbct.Set<ConfigurationEntry>().AsNoTracking(),
17+
opt =>
18+
{
19+
opt.LogTo = Console.WriteLine;
20+
});
2521

26-
Console.WriteLine($"Deleted: {deleteResult.AffectedRows} row(s)");
22+
Console.WriteLine($"Deleted: {deleteResult.AffectedRows} row(s)");
2723

28-
var configurationEntries = new List<ConfigurationEntry>();
24+
var configurationEntries = new List<ConfigurationEntry>();
2925

30-
for (int i = 0; i < 1000; i++)
31-
{
32-
configurationEntries.Add(new ConfigurationEntry
33-
{
34-
Key = $"Key{i}",
35-
Value = $"Value{i}",
36-
CreatedDateTime = DateTimeOffset.Now,
37-
});
38-
}
39-
40-
dbct.BulkInsert(configurationEntries,
41-
opt =>
42-
{
43-
opt.LogTo = Console.WriteLine;
44-
});
26+
for (int i = 0; i < 1000; i++)
27+
{
28+
configurationEntries.Add(new ConfigurationEntry
29+
{
30+
Key = $"Key{i}",
31+
Value = $"Value{i}",
32+
CreatedDateTime = DateTimeOffset.Now,
33+
});
34+
}
4535

46-
foreach (var row in configurationEntries)
47-
{
48-
row.Key += "xx";
49-
row.UpdatedDateTime = DateTimeOffset.Now;
50-
row.IsSensitive = true;
51-
row.Description = row.Id.ToString();
52-
}
36+
dbct.BulkInsert(configurationEntries,
37+
opt =>
38+
{
39+
opt.LogTo = Console.WriteLine;
40+
});
5341

54-
var updateResult = dbct.BulkUpdate(configurationEntries,
55-
x => new { x.Key, x.UpdatedDateTime, x.IsSensitive, x.Description },
56-
opt =>
57-
{
58-
opt.LogTo = Console.WriteLine;
59-
});
42+
foreach (var row in configurationEntries)
43+
{
44+
row.Key += "xx";
45+
row.UpdatedDateTime = DateTimeOffset.Now;
46+
row.IsSensitive = true;
47+
row.Description = row.Id.ToString();
48+
}
6049

61-
Console.WriteLine($"Updated: {updateResult.AffectedRows} row(s)");
50+
var updateResult = dbct.BulkUpdate(configurationEntries,
51+
x => new { x.Key, x.UpdatedDateTime, x.IsSensitive, x.Description },
52+
opt =>
53+
{
54+
opt.LogTo = Console.WriteLine;
55+
});
6256

63-
configurationEntries.Add(new ConfigurationEntry
64-
{
65-
Key = $"Key{1001}",
66-
Value = $"Value{1001}",
67-
CreatedDateTime = DateTimeOffset.Now,
68-
});
57+
Console.WriteLine($"Updated: {updateResult.AffectedRows} row(s)");
6958

70-
var mergeResult = dbct.BulkMerge(configurationEntries,
71-
x => x.Id,
72-
x => new { x.Key, x.UpdatedDateTime, x.IsSensitive, x.Description },
73-
x => new { x.Key, x.Value, x.IsSensitive, x.CreatedDateTime },
74-
opt =>
75-
{
76-
opt.LogTo = Console.WriteLine;
77-
});
59+
configurationEntries.Add(new ConfigurationEntry
60+
{
61+
Key = $"Key{1001}",
62+
Value = $"Value{1001}",
63+
CreatedDateTime = DateTimeOffset.Now,
64+
});
7865

79-
Console.WriteLine($"Updated: {mergeResult.UpdatedRows} row(s)");
80-
Console.WriteLine($"Inserted: {mergeResult.InsertedRows} row(s)");
81-
Console.WriteLine($"Affected: {mergeResult.AffectedRows} row(s)");
82-
}
66+
var mergeResult = dbct.BulkMerge(configurationEntries,
67+
x => x.Id,
68+
x => new { x.Key, x.UpdatedDateTime, x.IsSensitive, x.Description },
69+
x => new { x.Key, x.Value, x.IsSensitive, x.CreatedDateTime },
70+
opt =>
71+
{
72+
opt.LogTo = Console.WriteLine;
73+
});
8374

84-
Console.WriteLine("Finished!");
85-
Console.ReadLine();
86-
}
75+
Console.WriteLine($"Updated: {mergeResult.UpdatedRows} row(s)");
76+
Console.WriteLine($"Inserted: {mergeResult.InsertedRows} row(s)");
77+
Console.WriteLine($"Affected: {mergeResult.AffectedRows} row(s)");
8778
}
79+
80+
Console.WriteLine("Finished!");
81+
Console.ReadLine();

src/EntityFrameworkCore.SqlServer.SimpleBulks/Extensions/DbContextExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public static bool IsEntityType(this DbContext dbContext, Type type)
4747

4848
public static SqlConnection GetSqlConnection(this DbContext dbContext)
4949
{
50-
return dbContext.Database.GetDbConnection().AsSqlConnection();
50+
return dbContext.Database.GetDbConnection() as SqlConnection;
5151
}
5252

5353
public static SqlTransaction GetCurrentSqlTransaction(this DbContext dbContext)

src/EntityFrameworkCore.SqlServer.SimpleBulks/Extensions/IDbConnectionExtensions.cs renamed to src/EntityFrameworkCore.SqlServer.SimpleBulks/Extensions/SqlConnectionExtensions.cs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,9 @@
33

44
namespace EntityFrameworkCore.SqlServer.SimpleBulks.Extensions;
55

6-
public static class IDbConnectionExtensions
6+
public static class SqlConnectionExtensions
77
{
8-
public static SqlConnection AsSqlConnection(this IDbConnection connection)
9-
{
10-
return connection as SqlConnection;
11-
}
12-
13-
public static void EnsureOpen(this IDbConnection connection)
8+
public static void EnsureOpen(this SqlConnection connection)
149
{
1510
var connectionState = connection.State;
1611

@@ -20,7 +15,7 @@ public static void EnsureOpen(this IDbConnection connection)
2015
}
2116
}
2217

23-
public static void EnsureClosed(this IDbConnection connection)
18+
public static void EnsureClosed(this SqlConnection connection)
2419
{
2520
var connectionState = connection.State;
2621

@@ -30,7 +25,7 @@ public static void EnsureClosed(this IDbConnection connection)
3025
}
3126
}
3227

33-
public static IDbCommand CreateTextCommand(this IDbConnection connection, IDbTransaction transaction, string commandText, BulkOptions options = null)
28+
public static SqlCommand CreateTextCommand(this SqlConnection connection, SqlTransaction transaction, string commandText, BulkOptions options = null)
3429
{
3530
options ??= new BulkOptions()
3631
{
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
using EntityFrameworkCore.SqlServer.SimpleBulks.Extensions;
2+
using Microsoft.EntityFrameworkCore;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq.Expressions;
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
9+
namespace EntityFrameworkCore.SqlServer.SimpleBulks.TempTable;
10+
11+
public static class DbContextAsyncExtensions
12+
{
13+
public static Task<string> CreateTempTableAsync<T>(this DbContext dbContext, IEnumerable<T> data, Expression<Func<T, object>> columnNamesSelector, Action<TempTableOptions> configureOptions = null, CancellationToken cancellationToken = default)
14+
{
15+
var connection = dbContext.GetSqlConnection();
16+
var transaction = dbContext.GetCurrentSqlTransaction();
17+
18+
var isEntityType = dbContext.IsEntityType(typeof(T));
19+
20+
IReadOnlyDictionary<string, string> columnNameMappings = null;
21+
IReadOnlyDictionary<string, string> columnTypeMappings = null;
22+
23+
if (isEntityType)
24+
{
25+
columnNameMappings = dbContext.GetColumnNames(typeof(T));
26+
columnTypeMappings = dbContext.GetColumnTypes(typeof(T));
27+
}
28+
29+
return new TempTableBuilder<T>(connection, transaction)
30+
.WithData(data)
31+
.WithColumns(columnNamesSelector)
32+
.WithDbColumnMappings(columnNameMappings)
33+
.WithDbColumnTypeMappings(columnTypeMappings)
34+
.ConfigureTempTableOptions(configureOptions)
35+
.ExecuteAsync(cancellationToken);
36+
}
37+
38+
public static Task<string> CreateTempTableAsync<T>(this DbContext dbContext, IEnumerable<T> data, Action<TempTableOptions> configureOptions = null, CancellationToken cancellationToken = default)
39+
{
40+
var connection = dbContext.GetSqlConnection();
41+
var transaction = dbContext.GetCurrentSqlTransaction();
42+
43+
var isEntityType = dbContext.IsEntityType(typeof(T));
44+
45+
IReadOnlyDictionary<string, string> columnNameMappings = null;
46+
IReadOnlyDictionary<string, string> columnTypeMappings = null;
47+
IEnumerable<string> columnNames = typeof(T).GetDbColumnNames();
48+
49+
if (isEntityType)
50+
{
51+
columnNameMappings = dbContext.GetColumnNames(typeof(T));
52+
columnTypeMappings = dbContext.GetColumnTypes(typeof(T));
53+
}
54+
55+
return new TempTableBuilder<T>(connection, transaction)
56+
.WithData(data)
57+
.WithColumns(columnNames)
58+
.WithDbColumnMappings(columnNameMappings)
59+
.WithDbColumnTypeMappings(columnTypeMappings)
60+
.ConfigureTempTableOptions(configureOptions)
61+
.ExecuteAsync(cancellationToken);
62+
}
63+
}

src/EntityFrameworkCore.SqlServer.SimpleBulks/TempTable/TempTableBuilder.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
using System;
44
using System.Collections.Generic;
55
using System.Linq.Expressions;
6+
using System.Threading;
7+
using System.Threading.Tasks;
68

79
namespace EntityFrameworkCore.SqlServer.SimpleBulks.TempTable;
810

@@ -111,4 +113,9 @@ private void Log(string message)
111113
{
112114
_options?.LogTo?.Invoke($"{DateTimeOffset.Now:yyyy-MM-dd HH:mm:ss.fff zzz} [TempTable]: {message}");
113115
}
116+
117+
public Task<string> ExecuteAsync(CancellationToken cancellationToken = default)
118+
{
119+
return Task.FromResult(Execute());
120+
}
114121
}

0 commit comments

Comments
 (0)