Skip to content

Commit

Permalink
Patching the null argument bug
Browse files Browse the repository at this point in the history
  • Loading branch information
artiomchi committed Nov 28, 2024
1 parent 08a2f7b commit 1373858
Show file tree
Hide file tree
Showing 9 changed files with 45 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Also supports injecting sql command generators to add support for other provider
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageTags>Entity Framework Core entity-framework-core EF EntityFramework EntityFrameworkCore EFCore Upsert</PackageTags>
<PackageReadmeFile>README.md</PackageReadmeFile>
<VersionPrefix>8.1.0</VersionPrefix>
<VersionPrefix>8.1.1</VersionPrefix>
<PackageReleaseNotes>
v8.1.0
+ Adding initial support for Oracle DB! (Thanks to @dadyarri)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,7 @@ protected virtual string GetTableName(IEntityType entityType)
var constantArgumentSourceValues = updateExpressions?.Select(e => e.Value);
if (updateConditionExpression != null)
constantArgumentSourceValues = constantArgumentSourceValues?.Append(updateConditionExpression) ?? [updateConditionExpression];
var expressionConstants = constantArgumentSourceValues
?.SelectMany(v => v.GetConstantValues())
.Where(c => c.Value != null)
.ToArray();
var expressionConstants = constantArgumentSourceValues?.SelectMany(v => v.GetConstantValues()).ToArray();

var entitiesProcessed = 0;
var singleEntityArguments = newEntities[0].Count + (expressionConstants?.Length ?? 0);
Expand Down Expand Up @@ -456,7 +453,7 @@ private DbParameter PrepareDbCommandArgument(DbCommand dbCommand, IRelationalTyp
{
dbParameter = dbCommand.CreateParameter();
dbParameter.Direction = ParameterDirection.Input;
dbParameter.Value = constantValue.Value;
dbParameter.Value = constantValue.Value ?? DBNull.Value;
dbParameter.ParameterName = Parameter(constantValue.ArgumentIndex);
}
return dbParameter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1379,6 +1379,34 @@ public void Upsert_NullableKeys()
k => (k.ID1, k.ID2, k.Value).Should().Be((1, 3, "Third")));
}

[Fact]
public void Upsert_WithNullValues()
{
ResetDb();
using var dbContext = new TestDbContext(_fixture.DataContextOptions);

var newItem2 = new TestEntity();
var newItem = new TestEntity
{
Num1 = 1,
Num2 = 7,
Text1 = "Test",
Text2 = "Value",
};

dbContext.TestEntities.Upsert(newItem)
.On(j => j.Num1)
.WhenMatched((je, jn) => new TestEntity
{
Text1 = newItem2.Text1,
Text2 = null,
})
.Run();

dbContext.TestEntities.OrderBy(t => t.ID).Should().SatisfyRespectively(
test => test.Should().MatchModel(newItem));
}

[Fact]
public void Upsert_CompositeExpression_New()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public MySqlUpsertCommandRunnerTests()
"VALUES (@p0, @p1, @p2, @p3) " +
"ON DUPLICATE KEY UPDATE `Name` = IF (( `Total` > @p5 ) AND ( `Status` != VALUES(`Status`) ), @p4, `Name`)";

protected override string Update_Condition_NullCheck_Sql =>
protected override string Update_Condition_NullCheck_AlsoNullValue_Sql =>
"INSERT INTO `TestEntity` (`ID`, `Name`, `Status`, `Total`) " +
"VALUES (@p0, @p1, @p2, @p3) " +
"ON DUPLICATE KEY UPDATE `Name` = IF (`Status` IS NOT NULL, @p4, `Name`)";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public OracleUpsertCommandRunnerTests()
"WHEN NOT MATCHED THEN INSERT (\"ID\", \"Name\", \"Status\", \"Total\") VALUES (s.\"ID\", s.\"Name\", s.\"Status\", s.\"Total\") " +
"WHEN MATCHED THEN UPDATE SET t.\"Name\" = :p4 WHERE ( t.\"Total\" > :p5 ) AND ( t.\"Status\" != s.\"Status\" )";

protected override string Update_Condition_NullCheck_Sql =>
protected override string Update_Condition_NullCheck_AlsoNullValue_Sql =>
"MERGE INTO \"TestEntity\" t " +
"USING (SELECT :p0 AS \"ID\", :p1 AS \"Name\", :p2 AS \"Status\", :p3 AS \"Total\" FROM dual) s " +
"ON (t.\"ID\" = s.\"ID\") " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public PostgreSqlUpsertCommandRunnerTests()
"DO UPDATE SET \"Name\" = @p4 " +
"WHERE ( \"T\".\"Total\" > @p5 ) AND ( \"T\".\"Status\" != EXCLUDED.\"Status\" )";

protected override string Update_Condition_NullCheck_Sql =>
protected override string Update_Condition_NullCheck_AlsoNullValue_Sql =>
"INSERT INTO \"TestEntity\" AS \"T\" (\"ID\", \"Name\", \"Status\", \"Total\") " +
"VALUES (@p0, @p1, @p2, @p3) ON CONFLICT (\"ID\") " +
"DO UPDATE SET \"Name\" = @p4 " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,20 +284,25 @@ public void SqlSyntaxRunner_Update_Condition_AndCondition()
Arg.Any<IEnumerable<object>>());
}

protected abstract string Update_Condition_NullCheck_Sql { get; }
protected abstract string Update_Condition_NullCheck_AlsoNullValue_Sql { get; }
[Fact]
public void SqlSyntaxRunner_Update_Condition_NullCheck()
public void SqlSyntaxRunner_Update_Condition_NullCheck_AlsoNullValue()
{
var ent = new TestEntity
{
Name = null,
};

_dbContext.Upsert(new TestEntity())
.WhenMatched(e => new TestEntity
{
Name = "new"
Name = ent.Name
})
.UpdateIf(e => e.Status != null)
.Run();

_rawSqlBuilder.Received().Build(
Update_Condition_NullCheck_Sql,
Update_Condition_NullCheck_AlsoNullValue_Sql,
Arg.Any<IEnumerable<object>>());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public SqlServerUpsertCommandRunnerTests()
"WHEN NOT MATCHED BY TARGET THEN INSERT ([ID], [Name], [Status], [Total]) VALUES ([ID], [Name], [Status], [Total]) " +
"WHEN MATCHED AND ( [T].[Total] > @p5 ) AND ( [T].[Status] != [S].[Status] ) THEN UPDATE SET [Name] = @p4;";

protected override string Update_Condition_NullCheck_Sql =>
protected override string Update_Condition_NullCheck_AlsoNullValue_Sql =>
"MERGE INTO [TestEntity] WITH (HOLDLOCK) AS [T] " +
"USING ( VALUES (@p0, @p1, @p2, @p3) ) AS [S] ([ID], [Name], [Status], [Total]) " +
"ON [T].[ID] = [S].[ID] " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public SqliteUpsertCommandRunnerTests()
"DO UPDATE SET \"Name\" = @p4 " +
"WHERE ( \"T\".\"Total\" > @p5 ) AND ( \"T\".\"Status\" != EXCLUDED.\"Status\" )";

protected override string Update_Condition_NullCheck_Sql =>
protected override string Update_Condition_NullCheck_AlsoNullValue_Sql =>
"INSERT INTO \"TestEntity\" AS \"T\" (\"ID\", \"Name\", \"Status\", \"Total\") " +
"VALUES (@p0, @p1, @p2, @p3) ON CONFLICT (\"ID\") " +
"DO UPDATE SET \"Name\" = @p4 " +
Expand Down

0 comments on commit 1373858

Please sign in to comment.