【发布时间】:2021-05-13 04:49:56
【问题描述】:
我正在使用带有 SQL Server 的 EF Core 5,并且我有以下简单实体:
public class Person
{
public Guid Id { get; set; }
public string Name { get; set; }
}
在 DbContext 中添加为:
public DbSet<Person> People { get; set; }
我运行add-migration Person 得到以下生成的迁移代码:
public partial class Person : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "People",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Name = table.Column<string>(type: "nvarchar(max)", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_People", x => x.Id);
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "People");
}
}
然后我运行update-database 在数据库中创建这个Person 表。
context.People.Add(new Person() { Name = "John" });
context.SaveChanges();
查看 EF 日志,我看到执行了 SQL 命令:
Executed DbCommand (21ms) [Parameters=[@p0='115b2a5d-56b7-42c8-2f42-08d8cd03a34e', @p1='John' (Size = 4000)], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
INSERT INTO [People] ([Id], [Name])
VALUES (@p0, @p1);
我注意到 Id 的第一个参数是 @p0='115b2a5d-56b7-42c8-2f42-08d8cd03a34e',所以这意味着 Guid 是由 EF 生成的,而不是由数据库生成的。我希望它由数据库生成。
所以我在Id 属性中添加了以下属性:
public class Person
{
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public string Name { get; set; }
}
但是当我创建一个新的迁移时,它给了我空的 Up() 和 Down() 方法,这意味着从 EF 的角度来看,数据库中不应有任何更改。为什么是这样?以及如何让 EF Core 5 创建由数据库自动生成的 Id 主键。
【问题讨论】:
-
迁移可能不会改变,但是日志中生成的SQL会改变吗?
-
Fluent API 选项适合您吗? stackoverflow.com/questions/25094711/…
-
如果你这样做,使用这些属性,从一开始(擦除数据库并重新开始)它是否默认 NewID()?
-
@DavidG 刚刚查看了日志,并没有改变EF生成的SQL,所以参数
@p0还是传给了数据库。 -
@madoxdev,我刚刚尝试过这样的 Fluent API:“modelBuilder.Entity
().Property(x => x.Id).HasDefaultValueSql("NEWID()");"但下次我尝试添加新的 Person我得到SqlException: Cannot insert the value NULL into column 'Id', table 'dbo.People'; column does not allow nulls. UPDATE fails. The statement has been terminated.
标签: c# sql-server .net-core entity-framework-core