Skip to content

Commit 829a496

Browse files
author
fabien.menager
committed
Rename and add tests for entity insertion with conflict handling
1 parent be9717b commit 829a496

2 files changed

Lines changed: 96 additions & 2 deletions

File tree

tests/EntityFrameworkCore.ExecuteInsert.Tests/EntityFrameworkCore.ExecuteInsert.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
<PrivateAssets>all</PrivateAssets>
2121
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2222
</PackageReference>
23+
<PackageReference Include="Xunit.SkippableFact" Version="1.5.23" />
2324
<PackageReference Include="Testcontainers" Version="4.4.0" />
2425
<PackageReference Include="Testcontainers.PostgreSql" Version="4.4.0" />
2526
<PackageReference Include="Testcontainers.MsSql" Version="4.4.0" />

tests/EntityFrameworkCore.ExecuteInsert.Tests/Tests/Basic/BasicTestsBase.cs

Lines changed: 95 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ await DbContainer.DbContext.ExecuteInsertWithIdentityAsync(entities, o =>
6565
}
6666

6767
[Fact]
68-
public async Task InsertsEntitiesWithConflictSuccessfully()
68+
public async Task InsertsEntitiesWithConflict_SingleColumn()
6969
{
7070
DbContainer.DbContext.TestEntities.Add(new TestEntity { Name = "Entity1" });
7171
await DbContainer.DbContext.SaveChangesAsync();
@@ -101,6 +101,99 @@ await DbContainer.DbContext.ExecuteInsertAsync(entities, o =>
101101
Assert.Contains(insertedEntities, e => e.Name == "Entity2");
102102
}
103103

104+
[Fact]
105+
public async Task InsertsEntitiesWithConflict_DoNothing()
106+
{
107+
DbContainer.DbContext.TestEntities.Add(new TestEntity { Name = "Entity1" });
108+
await DbContainer.DbContext.SaveChangesAsync();
109+
DbContainer.DbContext.ChangeTracker.Clear();
110+
111+
var entities = new List<TestEntity>
112+
{
113+
new TestEntity { Name = "Entity1" },
114+
new TestEntity { Name = "Entity2" },
115+
};
116+
117+
await DbContainer.DbContext.ExecuteInsertAsync(entities, o =>
118+
{
119+
o.MoveRows = true;
120+
}, new OnConflictOptions<TestEntity>
121+
{
122+
Match = e => new { e.Name }
123+
// Pas de Update => DO NOTHING
124+
});
125+
126+
var insertedEntities = DbContainer.DbContext.TestEntities.ToList();
127+
Assert.Equal(2, insertedEntities.Count);
128+
Assert.Contains(insertedEntities, e => e.Name == "Entity1");
129+
Assert.Contains(insertedEntities, e => e.Name == "Entity2");
130+
}
131+
132+
[SkippableFact]
133+
public async Task InsertsEntitiesWithConflict_Condition()
134+
{
135+
Skip.If(DbContainer.DbContext.Database.ProviderName!.Contains("Npgsql", StringComparison.InvariantCultureIgnoreCase));
136+
137+
DbContainer.DbContext.TestEntities.Add(new TestEntity { Name = "Entity1", Price = 10 });
138+
await DbContainer.DbContext.SaveChangesAsync();
139+
DbContainer.DbContext.ChangeTracker.Clear();
140+
141+
var entities = new List<TestEntity>
142+
{
143+
new TestEntity { Name = "Entity1", Price = 20 },
144+
new TestEntity { Name = "Entity2", Price = 30 },
145+
};
146+
147+
await DbContainer.DbContext.ExecuteInsertAsync(entities, o =>
148+
{
149+
o.MoveRows = true;
150+
}, new OnConflictOptions<TestEntity>
151+
{
152+
Match = e => new { e.Name },
153+
Update = e => new TestEntity { Price = e.Price },
154+
Condition = "EXCLUDED.Price > TestEntities.Price"
155+
});
156+
157+
var insertedEntities = DbContainer.DbContext.TestEntities.ToList();
158+
Assert.Equal(2, insertedEntities.Count);
159+
Assert.Contains(insertedEntities, e => e.Name == "Entity1" && e.Price == 20);
160+
Assert.Contains(insertedEntities, e => e.Name == "Entity2" && e.Price == 30);
161+
}
162+
163+
[Fact]
164+
public async Task InsertsEntitiesWithConflict_MultipleColumns()
165+
{
166+
DbContainer.DbContext.TestEntities.Add(new TestEntity { Name = "Entity1", Price = 10 });
167+
await DbContainer.DbContext.SaveChangesAsync();
168+
DbContainer.DbContext.ChangeTracker.Clear();
169+
170+
var entities = new List<TestEntity>
171+
{
172+
new TestEntity { Name = "Entity1", Price = 20, Identifier = Guid.NewGuid() },
173+
new TestEntity { Name = "Entity2", Price = 30, Identifier = Guid.NewGuid() },
174+
};
175+
176+
await DbContainer.DbContext.ExecuteInsertAsync(entities, o =>
177+
{
178+
o.MoveRows = true;
179+
}, new OnConflictOptions<TestEntity>
180+
{
181+
Match = e => new { e.Name },
182+
Update = e => new TestEntity {
183+
Name = e.Name + " - Conflict",
184+
Price = 0,
185+
}
186+
});
187+
188+
var insertedEntities = DbContainer.DbContext.TestEntities.ToList();
189+
Assert.Equal(2, insertedEntities.Count);
190+
Assert.Equal(1, insertedEntities.Count(e => e.Name == "Entity1 - Conflict"));
191+
Assert.Contains(insertedEntities, e => e.Name == "Entity2");
192+
193+
var entity1 = insertedEntities.First(e => e.Name == "Entity1 - Conflict");
194+
Assert.Equal(0, entity1.Price);
195+
}
196+
104197
[Fact]
105198
public async Task DoesNothingWhenEntitiesAreEmpty()
106199
{
@@ -116,7 +209,7 @@ public async Task DoesNothingWhenEntitiesAreEmpty()
116209
}
117210

118211
[Fact]
119-
public async Task InsertsThousandsOfEntitiesSuccessfully()
212+
public async Task InsertsEntities_Many()
120213
{
121214
// Arrange
122215
const int count = 156055;

0 commit comments

Comments
 (0)