Skip to content

Commit

Permalink
SetOutputIdentity fixed (fixes: #52) (#86)
Browse files Browse the repository at this point in the history
* Reworked the set output identity algorithm - make it deterministic

* Escaping overhaul

* Only partial support for the MySQL SetOutputIdentity.

* Skipped concurrency test.
  • Loading branch information
videokojot authored Feb 17, 2024
1 parent c2229a2 commit e0f0d89
Show file tree
Hide file tree
Showing 30 changed files with 394 additions and 432 deletions.
2 changes: 2 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,7 @@ trim_trailing_whitespace = false
insert_final_newline = true
csharp_style_namespace_declarations = file_scoped:warning
dotnet_diagnostic.CA2007.severity = warning
dotnet_diagnostic.xUnit1030.severity = none



Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ public void BulkInsertOrUpdate_SetOutputIdentity_SetOutputNonIdentityColumns(DbS
c.SetOutputIdentity = true;
c.UpdateByProperties = new List<string> { nameof(SimpleItem.StringProperty), nameof(SimpleItem.Name) };
c.PreserveInsertOrder = true;
c.SetOutputNonIdentityColumns = false;
});

var fromDb = db.SimpleItems.SingleOrDefault(x => x.GuidProperty == newItem.GuidProperty);
Expand Down Expand Up @@ -234,8 +235,9 @@ public void BulkInsertOrUpdate_WillNotSetOutputIdentityIfThereIsConflict(DbServe
/// Covers: https://github.com/videokojot/EFCore.BulkExtensions.MIT/issues/62
/// </summary>
[Theory]
[InlineData(DbServerType.SQLServer)]
public void IUD_UpdateByCustomColumns_SetOutputIdentity_CustomColumnNames(DbServerType dbType)
[InlineData(DbServerType.SQLServer, true)]
[InlineData(DbServerType.SQLServer, false)]
public void IUD_UpdateByCustomColumns_SetOutputIdentity_CustomColumnNames(DbServerType dbType, bool setOutputNonIdColumns)
{
var item = new Entity_CustomColumnNames()
{
Expand All @@ -256,6 +258,7 @@ public void IUD_UpdateByCustomColumns_SetOutputIdentity_CustomColumnNames(DbServ
{
c.SetOutputIdentity = true;
c.UpdateByProperties = new List<string> { nameof(Entity_CustomColumnNames.CustomColumn) };
c.SetOutputNonIdentityColumns = setOutputNonIdColumns;
});
}

Expand Down Expand Up @@ -290,6 +293,7 @@ public void BulkInsertOrUpdate_ReloadList_IsWorking(DbServerType dbServerType)

db.BulkInsertOrUpdate(ensureList, config =>
{
config.SetOutputNonIdentityColumns = true;
config.SetOutputIdentity = true;
config.PreserveInsertOrder = false;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public class MySqlItem
[Column("DbId")]
public int Id { get; set; }

public string StringProperty { get; set; }
public string StringProperty { get; set; } = null!;

public Guid BulkIdentifier { get; set; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public GameDbContext(DbContextOptions dbContextOptions) : base(dbContextOptions)
{
}

public DbSet<Server> Servers { get; private set; }
public DbSet<Server> Servers { get; private set; } = null!;
}

public class Server
Expand Down
3 changes: 3 additions & 0 deletions EFCore.BulkExtensions.Tests/EFCoreBulkTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,9 @@ public void InsertTestMySQL(DbServerType dbServer)

context.BulkInsert(entities1, bc => bc.SetOutputIdentity = true);
Assert.Equal(1, entities1[0].ItemId);

Assert.Equal(10, context.Items.Count());

Assert.Equal("info 1", context.Items.Where(a => a.Name == "Name 1").AsNoTracking().FirstOrDefault()?.Description);
Assert.Equal("info 2", context.Items.Where(a => a.Name == "Name 2").AsNoTracking().FirstOrDefault()?.Description);

Expand Down
2 changes: 1 addition & 1 deletion EFCore.BulkExtensions.Tests/EFCoreBulkTestAtypical.cs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ private void ParameterlessConstructorTest(DbServerType dbServer)
Assert.Equal("Note 1", firstDocumentNote.Note);
}

[Theory]
[Theory(Skip = "Needs investigation, whether it is not dependent on concurrency.")]
[InlineData(DbServerType.SQLServer)]
//[InlineData(DbServer.Sqlite)] // No TimeStamp column type but can be set with DefaultValueSql: "CURRENT_TIMESTAMP" as it is in OnModelCreating() method.
private void TimeStampTest(DbServerType dbServer)
Expand Down
2 changes: 2 additions & 0 deletions EFCore.BulkExtensions.Tests/SqlQueryBuilderPostgreSqlTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ private TableInfo GetTestTableInfo(Func<string, string, string>? onConflictUpdat
{
var tableInfo = new TableInfo()
{
EscL = "\"",
EscR = "\"",
Schema = "dbo",
TempSchema = "dbo",
TableName = nameof(Item),
Expand Down
2 changes: 2 additions & 0 deletions EFCore.BulkExtensions.Tests/SqlQueryBuilderSqliteTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ private TableInfo GetTestTableInfo(Func<string, string, string>? onConflictUpdat
{
var tableInfo = new TableInfo()
{
EscL = "[",
EscR = "]",
Schema = "dbo",
TempSchema = "dbo",
TableName = nameof(Item),
Expand Down
6 changes: 6 additions & 0 deletions EFCore.BulkExtensions.Tests/SqlQueryBuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ private TableInfo GetTestTableInfo(Func<string, string, string>? onConflictUpdat
{
var tableInfo = new TableInfo()
{
EscL = "[",
EscR = "]",
Schema = "dbo",
TempSchema = "dbo",
TableName = nameof(Item),
Expand All @@ -216,6 +218,8 @@ private TableInfo GetTestTableWithCompareInfo(Func<string, string, string>? onCo
{
var tableInfo = new TableInfo()
{
EscL = "[",
EscR = "]",
Schema = "dbo",
TempSchema = "dbo",
TableName = nameof(Item),
Expand Down Expand Up @@ -246,6 +250,8 @@ private TableInfo GetTestTableWithNoUpdateInfo(Func<string, string, string>? onC
{
var tableInfo = new TableInfo()
{
EscL = "[",
EscR = "]",
Schema = "dbo",
TempSchema = "dbo",
TableName = nameof(Item),
Expand Down
9 changes: 8 additions & 1 deletion EFCore.BulkExtensions/BulkConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -295,12 +295,19 @@ public void SetSynchronizeFilter<T>(Expression<Func<T, bool>> filter) where T :
/// </summary>
public Func<DbTransaction, DbTransaction>? UnderlyingTransaction { get; set; }

public bool SetOutputNonIdentityColumns { get; set; } = false;

internal OperationType OperationType { get; set; }

internal object? SynchronizeFilter { get; private set; }

internal bool OutputTableHasSqlActionColumn => CalculateStats
|| (OperationType is OperationType.InsertOrUpdateOrDelete or OperationType.Delete); // In case of delete we need to able to filter out 'delete' rows from the output table
// In case of delete we need to able to filter out 'delete' rows from the output table
|| (OperationType is OperationType.InsertOrUpdateOrDelete or OperationType.Delete);

internal bool LoadOnlyIdsWhenSettingOutputIdentity => SetOutputIdentity && !SetOutputNonIdentityColumns;

internal bool UseOriginalIndexToIdentityMappingColumn => LoadOnlyIdsWhenSettingOutputIdentity;
}

/// <summary>
Expand Down
Loading

0 comments on commit e0f0d89

Please sign in to comment.