未验证 提交 2ccbf113 编写于 作者: S Shay Rojansky 提交者: GitHub

Sync dependencies (#2309)

EF Core -> 7.0.0-preview.3.22159.9
上级 b1d0ef42
<Project>
<PropertyGroup>
<EFCoreVersion>7.0.0-preview.2.22153.1</EFCoreVersion>
<MicrosoftExtensionsVersion>7.0.0-preview.2.22152.2</MicrosoftExtensionsVersion>
<EFCoreVersion>7.0.0-preview.3.22159.9</EFCoreVersion>
<MicrosoftExtensionsVersion>7.0.0-preview.3.22157.1</MicrosoftExtensionsVersion>
<NpgsqlVersion>7.0.0-preview.2</NpgsqlVersion>
</PropertyGroup>
......
......@@ -1428,7 +1428,8 @@ protected override void Generate(EnsureSchemaOperation operation, IModel? model,
sqlBuilder,
modificationCommand,
0,
overridingSystemValue);
overridingSystemValue,
out _);
}
builder.Append(sqlBuilder.ToString());
......
......@@ -12,14 +12,16 @@ public NpgsqlUpdateSqlGenerator(UpdateSqlGeneratorDependencies dependencies)
public override ResultSetMapping AppendInsertOperation(
StringBuilder commandStringBuilder,
IReadOnlyModificationCommand command,
int commandPosition)
=> AppendInsertOperation(commandStringBuilder, command, commandPosition, false);
int commandPosition,
out bool requiresTransaction)
=> AppendInsertOperation(commandStringBuilder, command, commandPosition, overridingSystemValue: false, out requiresTransaction);
public virtual ResultSetMapping AppendInsertOperation(
StringBuilder commandStringBuilder,
IReadOnlyModificationCommand command,
int commandPosition,
bool overridingSystemValue)
bool overridingSystemValue,
out bool requiresTransaction)
{
Check.NotNull(commandStringBuilder, nameof(commandStringBuilder));
Check.NotNull(command, nameof(command));
......@@ -32,6 +34,7 @@ public NpgsqlUpdateSqlGenerator(UpdateSqlGeneratorDependencies dependencies)
var readOperations = operations.Where(o => o.IsRead).ToArray();
AppendInsertCommandHeader(commandStringBuilder, command.TableName, command.Schema, writeOperations);
if (overridingSystemValue)
{
commandStringBuilder.AppendLine().Append("OVERRIDING SYSTEM VALUE");
......@@ -39,6 +42,7 @@ public NpgsqlUpdateSqlGenerator(UpdateSqlGeneratorDependencies dependencies)
AppendValuesHeader(commandStringBuilder, writeOperations);
AppendValues(commandStringBuilder, name, schema, writeOperations);
if (readOperations.Length > 0)
{
AppendReturningClause(commandStringBuilder, readOperations);
......@@ -46,13 +50,16 @@ public NpgsqlUpdateSqlGenerator(UpdateSqlGeneratorDependencies dependencies)
commandStringBuilder.Append(SqlGenerationHelper.StatementTerminator).AppendLine();
requiresTransaction = false;
return ResultSetMapping.NoResultSet;
}
public override ResultSetMapping AppendUpdateOperation(
StringBuilder commandStringBuilder,
IReadOnlyModificationCommand command,
int commandPosition)
int commandPosition,
out bool requiresTransaction)
{
Check.NotNull(commandStringBuilder, nameof(commandStringBuilder));
Check.NotNull(command, nameof(command));
......@@ -67,11 +74,16 @@ public NpgsqlUpdateSqlGenerator(UpdateSqlGeneratorDependencies dependencies)
AppendUpdateCommandHeader(commandStringBuilder, tableName, schemaName, writeOperations);
AppendWhereClause(commandStringBuilder, conditionOperations);
if (readOperations.Length > 0)
{
AppendReturningClause(commandStringBuilder, readOperations);
}
commandStringBuilder.Append(SqlGenerationHelper.StatementTerminator).AppendLine();
requiresTransaction = false;
return ResultSetMapping.NoResultSet;
}
......
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.EntityFrameworkCore.TestModels.StoreValueGenerationModel;
using Npgsql.EntityFrameworkCore.PostgreSQL.TestUtilities;
namespace Microsoft.EntityFrameworkCore.Update;
#nullable enable
public class StoreValueGenerationNpgsqlTest : StoreValueGenerationTestBase<
StoreValueGenerationNpgsqlTest.StoreValueGenerationNpgsqlFixture>
{
public StoreValueGenerationNpgsqlTest(StoreValueGenerationNpgsqlFixture fixture, ITestOutputHelper testOutputHelper)
: base(fixture)
{
fixture.TestSqlLoggerFactory.Clear();
fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper);
}
protected override bool ShouldCreateImplicitTransaction(
EntityState firstOperationType,
EntityState? secondOperationType,
GeneratedValues generatedValues,
bool withSameEntityType)
=> secondOperationType is not null;
protected override int ShouldExecuteInNumberOfCommands(
EntityState firstOperationType,
EntityState? secondOperationType,
GeneratedValues generatedValues,
bool withDatabaseGenerated)
=> 1;
#region Single operation
public override async Task Add_with_generated_values(bool async)
{
await base.Add_with_generated_values(async);
AssertSql(
@"@p0='1000'
INSERT INTO ""WithSomeDatabaseGenerated"" (""Data2"")
VALUES (@p0)
RETURNING ""Id"", ""Data1"";");
}
public override async Task Add_with_no_generated_values(bool async)
{
await base.Add_with_no_generated_values(async);
AssertSql(
@"@p0='100'
@p1='1000'
@p2='1000'
INSERT INTO ""WithNoDatabaseGenerated"" (""Id"", ""Data1"", ""Data2"")
VALUES (@p0, @p1, @p2);");
}
public override async Task Add_with_all_generated_values(bool async)
{
await base.Add_with_all_generated_values(async);
AssertSql(
@"INSERT INTO ""WithAllDatabaseGenerated""
DEFAULT VALUES
RETURNING ""Id"", ""Data1"", ""Data2"";");
}
public override async Task Modify_with_generated_values(bool async)
{
await base.Modify_with_generated_values(async);
AssertSql(
@"@p1='1'
@p0='1000'
UPDATE ""WithSomeDatabaseGenerated"" SET ""Data2"" = @p0
WHERE ""Id"" = @p1
RETURNING ""Data1"";");
}
public override async Task Modify_with_no_generated_values(bool async)
{
await base.Modify_with_no_generated_values(async);
AssertSql(
@"@p2='1'
@p0='1000'
@p1='1000'
UPDATE ""WithNoDatabaseGenerated"" SET ""Data1"" = @p0, ""Data2"" = @p1
WHERE ""Id"" = @p2;");
}
public override async Task Delete(bool async)
{
await base.Delete(async);
AssertSql(
@"@p0='1'
DELETE FROM ""WithSomeDatabaseGenerated""
WHERE ""Id"" = @p0;");
}
#endregion Single operation
#region Two operations with same entity type
public override async Task Add_Add_with_same_entity_type_and_generated_values(bool async)
{
await base.Add_Add_with_same_entity_type_and_generated_values(async);
AssertSql(
@"@p0='1000'
@p1='1001'
INSERT INTO ""WithSomeDatabaseGenerated"" (""Data2"")
VALUES (@p0)
RETURNING ""Id"", ""Data1"";
INSERT INTO ""WithSomeDatabaseGenerated"" (""Data2"")
VALUES (@p1)
RETURNING ""Id"", ""Data1"";");
}
public override async Task Add_Add_with_same_entity_type_and_no_generated_values(bool async)
{
await base.Add_Add_with_same_entity_type_and_no_generated_values(async);
AssertSql(
@"@p0='100'
@p1='1000'
@p2='1000'
@p3='101'
@p4='1001'
@p5='1001'
INSERT INTO ""WithNoDatabaseGenerated"" (""Id"", ""Data1"", ""Data2"")
VALUES (@p0, @p1, @p2);
INSERT INTO ""WithNoDatabaseGenerated"" (""Id"", ""Data1"", ""Data2"")
VALUES (@p3, @p4, @p5);");
}
public override async Task Add_Add_with_same_entity_type_and_all_generated_values(bool async)
{
await base.Add_Add_with_same_entity_type_and_all_generated_values(async);
AssertSql(
@"INSERT INTO ""WithAllDatabaseGenerated""
DEFAULT VALUES
RETURNING ""Id"", ""Data1"", ""Data2"";
INSERT INTO ""WithAllDatabaseGenerated""
DEFAULT VALUES
RETURNING ""Id"", ""Data1"", ""Data2"";");
}
public override async Task Modify_Modify_with_same_entity_type_and_generated_values(bool async)
{
await base.Modify_Modify_with_same_entity_type_and_generated_values(async);
AssertSql(
@"@p1='1'
@p0='1000'
@p3='2'
@p2='1001'
UPDATE ""WithSomeDatabaseGenerated"" SET ""Data2"" = @p0
WHERE ""Id"" = @p1
RETURNING ""Data1"";
UPDATE ""WithSomeDatabaseGenerated"" SET ""Data2"" = @p2
WHERE ""Id"" = @p3
RETURNING ""Data1"";");
}
public override async Task Modify_Modify_with_same_entity_type_and_no_generated_values(bool async)
{
await base.Modify_Modify_with_same_entity_type_and_no_generated_values(async);
AssertSql(
@"@p2='1'
@p0='1000'
@p1='1000'
@p5='2'
@p3='1001'
@p4='1001'
UPDATE ""WithNoDatabaseGenerated"" SET ""Data1"" = @p0, ""Data2"" = @p1
WHERE ""Id"" = @p2;
UPDATE ""WithNoDatabaseGenerated"" SET ""Data1"" = @p3, ""Data2"" = @p4
WHERE ""Id"" = @p5;");
}
public override async Task Delete_Delete_with_same_entity_type(bool async)
{
await base.Delete_Delete_with_same_entity_type(async);
AssertSql(
@"@p0='1'
@p1='2'
DELETE FROM ""WithSomeDatabaseGenerated""
WHERE ""Id"" = @p0;
DELETE FROM ""WithSomeDatabaseGenerated""
WHERE ""Id"" = @p1;");
}
#endregion Two operations with same entity type
#region Two operations with different entity types
public override async Task Add_Add_with_different_entity_types_and_generated_values(bool async)
{
await base.Add_Add_with_different_entity_types_and_generated_values(async);
AssertSql(
@"@p0='1000'
@p1='1001'
INSERT INTO ""WithSomeDatabaseGenerated"" (""Data2"")
VALUES (@p0)
RETURNING ""Id"", ""Data1"";
INSERT INTO ""WithSomeDatabaseGenerated2"" (""Data2"")
VALUES (@p1)
RETURNING ""Id"", ""Data1"";");
}
public override async Task Add_Add_with_different_entity_types_and_no_generated_values(bool async)
{
await base.Add_Add_with_different_entity_types_and_no_generated_values(async);
AssertSql(
@"@p0='100'
@p1='1000'
@p2='1000'
@p3='101'
@p4='1001'
@p5='1001'
INSERT INTO ""WithNoDatabaseGenerated"" (""Id"", ""Data1"", ""Data2"")
VALUES (@p0, @p1, @p2);
INSERT INTO ""WithNoDatabaseGenerated2"" (""Id"", ""Data1"", ""Data2"")
VALUES (@p3, @p4, @p5);");
}
public override async Task Add_Add_with_different_entity_types_and_all_generated_values(bool async)
{
await base.Add_Add_with_different_entity_types_and_all_generated_values(async);
AssertSql(
@"INSERT INTO ""WithAllDatabaseGenerated""
DEFAULT VALUES
RETURNING ""Id"", ""Data1"", ""Data2"";
INSERT INTO ""WithAllDatabaseGenerated2""
DEFAULT VALUES
RETURNING ""Id"", ""Data1"", ""Data2"";");
}
public override async Task Modify_Modify_with_different_entity_types_and_generated_values(bool async)
{
await base.Modify_Modify_with_different_entity_types_and_generated_values(async);
AssertSql(
@"@p1='1'
@p0='1000'
@p3='2'
@p2='1001'
UPDATE ""WithSomeDatabaseGenerated"" SET ""Data2"" = @p0
WHERE ""Id"" = @p1
RETURNING ""Data1"";
UPDATE ""WithSomeDatabaseGenerated2"" SET ""Data2"" = @p2
WHERE ""Id"" = @p3
RETURNING ""Data1"";");
}
public override async Task Modify_Modify_with_different_entity_types_and_no_generated_values(bool async)
{
await base.Modify_Modify_with_different_entity_types_and_no_generated_values(async);
AssertSql(
@"@p2='1'
@p0='1000'
@p1='1000'
@p5='2'
@p3='1001'
@p4='1001'
UPDATE ""WithNoDatabaseGenerated"" SET ""Data1"" = @p0, ""Data2"" = @p1
WHERE ""Id"" = @p2;
UPDATE ""WithNoDatabaseGenerated2"" SET ""Data1"" = @p3, ""Data2"" = @p4
WHERE ""Id"" = @p5;");
}
public override async Task Delete_Delete_with_different_entity_types(bool async)
{
await base.Delete_Delete_with_different_entity_types(async);
AssertSql(
@"@p0='1'
@p1='2'
DELETE FROM ""WithSomeDatabaseGenerated""
WHERE ""Id"" = @p0;
DELETE FROM ""WithSomeDatabaseGenerated2""
WHERE ""Id"" = @p1;");
}
#endregion Two operations with different entity types
public class StoreValueGenerationNpgsqlFixture : StoreValueGenerationFixtureBase
{
protected override ITestStoreFactory TestStoreFactory
=> NpgsqlTestStoreFactory.Instance;
protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context)
{
base.OnModelCreating(modelBuilder, context);
foreach (var name in new[]
{
nameof(StoreValueGenerationContext.WithSomeDatabaseGenerated),
nameof(StoreValueGenerationContext.WithSomeDatabaseGenerated2),
nameof(StoreValueGenerationContext.WithAllDatabaseGenerated),
nameof(StoreValueGenerationContext.WithAllDatabaseGenerated2)
})
{
ConfigureComputedColumn(modelBuilder.SharedTypeEntity<StoreValueGenerationData>(name).Property(w => w.Data1));
}
foreach (var name in new[]
{
nameof(StoreValueGenerationContext.WithAllDatabaseGenerated),
nameof(StoreValueGenerationContext.WithAllDatabaseGenerated2)
})
{
ConfigureComputedColumn(modelBuilder.SharedTypeEntity<StoreValueGenerationData>(name).Property(w => w.Data2));
}
void ConfigureComputedColumn(PropertyBuilder builder)
{
if (TestEnvironment.PostgresVersion >= new Version(12, 0))
{
// PG 12+ supports computed columns, but only stored (must be explicitly specified)
builder.Metadata.SetIsStored(true);
}
else
{
// Before PG 12, disable computed columns (but leave OnAddOrUpdate)
builder
.HasComputedColumnSql(null)
.HasDefaultValue(100)
.Metadata
.ValueGenerated = ValueGenerated.OnAddOrUpdate;
}
}
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册