Skip to content

Commit ef76eda

Browse files
committed
Initial Async Support
1 parent ce6db20 commit ef76eda

File tree

14 files changed

+2965
-0
lines changed

14 files changed

+2965
-0
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using EntityFrameworkCore.SqlServer.SimpleBulks.Tests.Database;
2+
using Xunit.Abstractions;
3+
4+
namespace EntityFrameworkCore.SqlServer.SimpleBulks.Tests.DbContextAsyncExtensions;
5+
6+
public abstract class BaseTest : IDisposable
7+
{
8+
protected readonly ITestOutputHelper _output;
9+
protected readonly SqlServerFixture _fixture;
10+
protected readonly TestDbContext _context;
11+
12+
protected BaseTest(ITestOutputHelper output, SqlServerFixture fixture, string dbPrefixName, string schema = "")
13+
{
14+
_output = output;
15+
_fixture = fixture;
16+
_context = GetDbContext(dbPrefixName, schema);
17+
_context.Database.EnsureCreated();
18+
}
19+
20+
public void Dispose()
21+
{
22+
_context.Database.EnsureDeleted();
23+
}
24+
25+
protected TestDbContext GetDbContext(string dbPrefixName, string schema)
26+
{
27+
return new TestDbContext(_fixture.GetConnectionString(dbPrefixName), schema);
28+
}
29+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
using EntityFrameworkCore.SqlServer.SimpleBulks.BulkDelete;
2+
using EntityFrameworkCore.SqlServer.SimpleBulks.BulkInsert;
3+
using EntityFrameworkCore.SqlServer.SimpleBulks.Tests.Database;
4+
using Microsoft.EntityFrameworkCore;
5+
using Xunit.Abstractions;
6+
7+
namespace EntityFrameworkCore.SqlServer.SimpleBulks.Tests.DbContextAsyncExtensions;
8+
9+
[Collection("SqlServerCollection")]
10+
public class BulkDeleteTests : BaseTest
11+
{
12+
public BulkDeleteTests(ITestOutputHelper output, SqlServerFixture fixture) : base(output, fixture, "EFCoreSimpleBulksTests.BulkDelete")
13+
{
14+
var tran = _context.Database.BeginTransaction();
15+
16+
var rows = new List<SingleKeyRow<int>>();
17+
var compositeKeyRows = new List<CompositeKeyRow<int, int>>();
18+
19+
for (int i = 0; i < 100; i++)
20+
{
21+
rows.Add(new SingleKeyRow<int>
22+
{
23+
Column1 = i,
24+
Column2 = "" + i,
25+
Column3 = DateTime.Now
26+
});
27+
28+
compositeKeyRows.Add(new CompositeKeyRow<int, int>
29+
{
30+
Id1 = i,
31+
Id2 = i,
32+
Column1 = i,
33+
Column2 = "" + i,
34+
Column3 = DateTime.Now
35+
});
36+
}
37+
38+
_context.BulkInsert(rows,
39+
row => new { row.Column1, row.Column2, row.Column3 });
40+
41+
_context.BulkInsert(compositeKeyRows,
42+
row => new { row.Id1, row.Id2, row.Column1, row.Column2, row.Column3 });
43+
44+
tran.Commit();
45+
}
46+
47+
[Theory]
48+
[InlineData(1)]
49+
[InlineData(100)]
50+
public async Task Bulk_Delete_Using_Linq_With_Transaction(int length)
51+
{
52+
var tran = _context.Database.BeginTransaction();
53+
54+
var rows = _context.SingleKeyRows.AsNoTracking().Take(length).ToList();
55+
var compositeKeyRows = _context.CompositeKeyRows.AsNoTracking().Take(length).ToList();
56+
57+
var deleteResult1 = await _context.BulkDeleteAsync(rows,
58+
options =>
59+
{
60+
options.LogTo = _output.WriteLine;
61+
});
62+
63+
var deleteResult2 = await _context.BulkDeleteAsync(compositeKeyRows,
64+
options =>
65+
{
66+
options.LogTo = _output.WriteLine;
67+
});
68+
69+
tran.Commit();
70+
71+
// Assert
72+
var dbRows = _context.SingleKeyRows.AsNoTracking().ToList();
73+
var dbCompositeKeyRows = _context.CompositeKeyRows.AsNoTracking().ToList();
74+
75+
Assert.Equal(length, deleteResult1.AffectedRows);
76+
Assert.Equal(length, deleteResult2.AffectedRows);
77+
78+
Assert.Equal(100 - length, dbRows.Count);
79+
Assert.Equal(100 - length, dbCompositeKeyRows.Count);
80+
}
81+
}
Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
using EntityFrameworkCore.SqlServer.SimpleBulks.BulkInsert;
2+
using EntityFrameworkCore.SqlServer.SimpleBulks.Tests.Database;
3+
using Microsoft.EntityFrameworkCore;
4+
using Xunit.Abstractions;
5+
6+
namespace EntityFrameworkCore.SqlServer.SimpleBulks.Tests.DbContextAsyncExtensions;
7+
8+
[Collection("SqlServerCollection")]
9+
public class BulkInsertTests : BaseTest
10+
{
11+
public BulkInsertTests(ITestOutputHelper output, SqlServerFixture fixture) : base(output, fixture, "EFCoreSimpleBulksTests.BulkInsert")
12+
{
13+
}
14+
15+
[Theory]
16+
[InlineData(1)]
17+
[InlineData(100)]
18+
public async Task Bulk_Insert_Using_Linq_Without_Transaction(int length)
19+
{
20+
var rows = new List<SingleKeyRow<int>>();
21+
var compositeKeyRows = new List<CompositeKeyRow<int, int>>();
22+
23+
for (int i = 0; i < length; i++)
24+
{
25+
rows.Add(new SingleKeyRow<int>
26+
{
27+
Column1 = i,
28+
Column2 = "" + i,
29+
Column3 = DateTime.Now,
30+
Season = Season.Autumn
31+
});
32+
33+
compositeKeyRows.Add(new CompositeKeyRow<int, int>
34+
{
35+
Id1 = i,
36+
Id2 = i,
37+
Column1 = i,
38+
Column2 = "" + i,
39+
Column3 = DateTime.Now,
40+
Season = Season.Autumn
41+
});
42+
}
43+
44+
await _context.BulkInsertAsync(rows,
45+
row => new { row.Column1, row.Column2, row.Column3, row.Season },
46+
options =>
47+
{
48+
options.LogTo = _output.WriteLine;
49+
});
50+
51+
await _context.BulkInsertAsync(compositeKeyRows,
52+
row => new { row.Id1, row.Id2, row.Column1, row.Column2, row.Column3, row.Season },
53+
options =>
54+
{
55+
options.LogTo = _output.WriteLine;
56+
});
57+
58+
59+
// Assert
60+
var dbRows = _context.SingleKeyRows.AsNoTracking().ToList();
61+
var dbCompositeKeyRows = _context.CompositeKeyRows.AsNoTracking().ToList();
62+
63+
for (int i = 0; i < length; i++)
64+
{
65+
Assert.Equal(rows[i].Id, dbRows[i].Id);
66+
Assert.Equal(rows[i].Column1, dbRows[i].Column1);
67+
Assert.Equal(rows[i].Column2, dbRows[i].Column2);
68+
Assert.Equal(rows[i].Column3, dbRows[i].Column3);
69+
Assert.Equal(rows[i].Season, dbRows[i].Season);
70+
71+
Assert.Equal(compositeKeyRows[i].Id1, dbCompositeKeyRows[i].Id1);
72+
Assert.Equal(compositeKeyRows[i].Id2, dbCompositeKeyRows[i].Id2);
73+
Assert.Equal(compositeKeyRows[i].Column1, dbCompositeKeyRows[i].Column1);
74+
Assert.Equal(compositeKeyRows[i].Column2, dbCompositeKeyRows[i].Column2);
75+
Assert.Equal(compositeKeyRows[i].Column3, dbCompositeKeyRows[i].Column3);
76+
Assert.Equal(compositeKeyRows[i].Season, dbCompositeKeyRows[i].Season);
77+
}
78+
}
79+
80+
[Theory]
81+
[InlineData(1)]
82+
[InlineData(100)]
83+
public async Task Bulk_Insert_Using_Linq_With_Transaction_Committed(int length)
84+
{
85+
var tran = _context.Database.BeginTransaction();
86+
87+
var rows = new List<SingleKeyRow<int>>();
88+
var compositeKeyRows = new List<CompositeKeyRow<int, int>>();
89+
90+
for (int i = 0; i < length; i++)
91+
{
92+
rows.Add(new SingleKeyRow<int>
93+
{
94+
Column1 = i,
95+
Column2 = "" + i,
96+
Column3 = DateTime.Now
97+
});
98+
99+
compositeKeyRows.Add(new CompositeKeyRow<int, int>
100+
{
101+
Id1 = i,
102+
Id2 = i,
103+
Column1 = i,
104+
Column2 = "" + i,
105+
Column3 = DateTime.Now
106+
});
107+
}
108+
109+
await _context.BulkInsertAsync(rows,
110+
row => new { row.Column1, row.Column2, row.Column3 });
111+
112+
await _context.BulkInsertAsync(compositeKeyRows,
113+
row => new { row.Id1, row.Id2, row.Column1, row.Column2, row.Column3 });
114+
115+
tran.Commit();
116+
117+
// Assert
118+
var dbRows = _context.SingleKeyRows.AsNoTracking().ToList();
119+
var dbCompositeKeyRows = _context.CompositeKeyRows.AsNoTracking().ToList();
120+
121+
for (int i = 0; i < length; i++)
122+
{
123+
Assert.Equal(rows[i].Id, dbRows[i].Id);
124+
Assert.Equal(rows[i].Column1, dbRows[i].Column1);
125+
Assert.Equal(rows[i].Column2, dbRows[i].Column2);
126+
Assert.Equal(rows[i].Column3, dbRows[i].Column3);
127+
128+
Assert.Equal(compositeKeyRows[i].Id1, dbCompositeKeyRows[i].Id1);
129+
Assert.Equal(compositeKeyRows[i].Id2, dbCompositeKeyRows[i].Id2);
130+
Assert.Equal(compositeKeyRows[i].Column1, dbCompositeKeyRows[i].Column1);
131+
Assert.Equal(compositeKeyRows[i].Column2, dbCompositeKeyRows[i].Column2);
132+
Assert.Equal(compositeKeyRows[i].Column3, dbCompositeKeyRows[i].Column3);
133+
}
134+
}
135+
136+
[Theory]
137+
[InlineData(1)]
138+
[InlineData(100)]
139+
public async Task Bulk_Insert_Using_Linq_With_Transaction_RolledBack(int length)
140+
{
141+
var tran = _context.Database.BeginTransaction();
142+
143+
var rows = new List<SingleKeyRow<int>>();
144+
var compositeKeyRows = new List<CompositeKeyRow<int, int>>();
145+
146+
for (int i = 0; i < length; i++)
147+
{
148+
rows.Add(new SingleKeyRow<int>
149+
{
150+
Column1 = i,
151+
Column2 = "" + i,
152+
Column3 = DateTime.Now
153+
});
154+
155+
compositeKeyRows.Add(new CompositeKeyRow<int, int>
156+
{
157+
Id1 = i,
158+
Id2 = i,
159+
Column1 = i,
160+
Column2 = "" + i,
161+
Column3 = DateTime.Now
162+
});
163+
}
164+
165+
await _context.BulkInsertAsync(rows,
166+
row => new { row.Column1, row.Column2, row.Column3 });
167+
168+
await _context.BulkInsertAsync(compositeKeyRows,
169+
row => new { row.Id1, row.Id2, row.Column1, row.Column2, row.Column3 });
170+
171+
tran.Rollback();
172+
173+
// Assert
174+
var dbRows = _context.SingleKeyRows.AsNoTracking().ToList();
175+
var dbCompositeKeyRows = _context.CompositeKeyRows.AsNoTracking().ToList();
176+
177+
Assert.Empty(dbRows);
178+
Assert.Empty(dbCompositeKeyRows);
179+
}
180+
181+
[Theory]
182+
[InlineData(1)]
183+
[InlineData(100)]
184+
public async Task Bulk_Insert_KeepIdentity(int length)
185+
{
186+
var configurationEntries = new List<ConfigurationEntry>();
187+
188+
for (int i = 0; i < length; i++)
189+
{
190+
configurationEntries.Add(new ConfigurationEntry
191+
{
192+
Id = Guid.NewGuid(),
193+
Key = $"Key{i}",
194+
Value = $"Value{i}",
195+
Description = string.Empty,
196+
CreatedDateTime = DateTimeOffset.Now,
197+
});
198+
}
199+
200+
await _context.BulkInsertAsync(configurationEntries, options =>
201+
{
202+
options.KeepIdentity = true;
203+
options.LogTo = _output.WriteLine;
204+
});
205+
206+
// Assert
207+
configurationEntries = configurationEntries.OrderBy(x => x.Id).ToList();
208+
var configurationEntriesInDb = _context.Set<ConfigurationEntry>().AsNoTracking().ToList().OrderBy(x => x.Id).ToList();
209+
210+
for (int i = 0; i < length; i++)
211+
{
212+
Assert.Equal(configurationEntries[i].Id, configurationEntriesInDb[i].Id);
213+
Assert.Equal(configurationEntries[i].Key, configurationEntriesInDb[i].Key);
214+
Assert.Equal(configurationEntries[i].Value, configurationEntriesInDb[i].Value);
215+
Assert.Equal(configurationEntries[i].Description, configurationEntriesInDb[i].Description);
216+
Assert.Equal(configurationEntries[i].CreatedDateTime, configurationEntriesInDb[i].CreatedDateTime);
217+
}
218+
}
219+
220+
[Theory]
221+
[InlineData(1)]
222+
[InlineData(100)]
223+
public async Task Bulk_Insert_Return_DbGeneratedId(int length)
224+
{
225+
var configurationEntries = new List<ConfigurationEntry>();
226+
227+
for (int i = 0; i < length; i++)
228+
{
229+
configurationEntries.Add(new ConfigurationEntry
230+
{
231+
Key = $"Key{i}",
232+
Value = $"Value{i}",
233+
Description = string.Empty,
234+
CreatedDateTime = DateTimeOffset.Now,
235+
});
236+
}
237+
238+
await _context.BulkInsertAsync(configurationEntries, options =>
239+
{
240+
options.LogTo = _output.WriteLine;
241+
});
242+
243+
// Assert
244+
configurationEntries = configurationEntries.OrderBy(x => x.Id).ToList();
245+
var configurationEntriesInDb = _context.Set<ConfigurationEntry>().AsNoTracking().ToList().OrderBy(x => x.Id).ToList();
246+
247+
for (int i = 0; i < length; i++)
248+
{
249+
Assert.NotEqual(Guid.Empty, configurationEntriesInDb[i].Id);
250+
Assert.Equal(configurationEntries[i].Id, configurationEntriesInDb[i].Id);
251+
Assert.Equal(configurationEntries[i].Key, configurationEntriesInDb[i].Key);
252+
Assert.Equal(configurationEntries[i].Value, configurationEntriesInDb[i].Value);
253+
Assert.Equal(configurationEntries[i].Description, configurationEntriesInDb[i].Description);
254+
Assert.Equal(configurationEntries[i].CreatedDateTime, configurationEntriesInDb[i].CreatedDateTime);
255+
}
256+
}
257+
}

0 commit comments

Comments
 (0)