Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
jobily
Efcore.Pg
提交
2ccbf113
E
Efcore.Pg
项目概览
jobily
/
Efcore.Pg
11 个月 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
E
Efcore.Pg
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
2ccbf113
编写于
3月 16, 2022
作者:
S
Shay Rojansky
提交者:
GitHub
3月 16, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Sync dependencies (#2309)
EF Core -> 7.0.0-preview.3.22159.9
上级
b1d0ef42
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
381 addition
and
7 deletion
+381
-7
Directory.Packages.props
Directory.Packages.props
+2
-2
src/EFCore.PG/Migrations/NpgsqlMigrationsSqlGenerator.cs
src/EFCore.PG/Migrations/NpgsqlMigrationsSqlGenerator.cs
+2
-1
src/EFCore.PG/Update/Internal/NpgsqlUpdateSqlGenerator.cs
src/EFCore.PG/Update/Internal/NpgsqlUpdateSqlGenerator.cs
+16
-4
test/EFCore.PG.FunctionalTests/Update/StoreValueGenerationNpgsqlTest.cs
....FunctionalTests/Update/StoreValueGenerationNpgsqlTest.cs
+361
-0
未找到文件。
Directory.Packages.props
浏览文件 @
2ccbf113
<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>
...
...
src/EFCore.PG/Migrations/NpgsqlMigrationsSqlGenerator.cs
浏览文件 @
2ccbf113
...
...
@@ -1428,7 +1428,8 @@ protected override void Generate(EnsureSchemaOperation operation, IModel? model,
sqlBuilder
,
modificationCommand
,
0
,
overridingSystemValue
);
overridingSystemValue
,
out
_
);
}
builder
.
Append
(
sqlBuilder
.
ToString
());
...
...
src/EFCore.PG/Update/Internal/NpgsqlUpdateSqlGenerator.cs
浏览文件 @
2ccbf113
...
...
@@ -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
;
}
...
...
test/EFCore.PG.FunctionalTests/Update/StoreValueGenerationNpgsqlTest.cs
0 → 100644
浏览文件 @
2ccbf113
// 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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录