【发布时间】:2020-07-30 13:48:11
【问题描述】:
我使用的是 EF Core 2.2.4。
这是我的实体:
public class Person
{
public int? Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
}
注意Person 有一个可为空类型的主键。这似乎由 EF Core 优雅地处理,最终实体获得了他们的 ID;我使用术语“nullable-type”PK 而不是“nullable PK”,因为其目的不是插入由数据库生成的具有 null PK 的记录,而是为了正确处理密钥还没有的实体的情况已生成。
正如我所说,一代似乎运作良好。但并非一切都运行良好。
AppDbContext dbc = new AppDbContext();
Person p1 = new Person() { Name = "Isaac", Surname = "Newton" };
dbc.Add(p1);
dbc.Remove(p1);
dbc.SaveChanges();
如果我运行此代码,dbc.Remove(p1) 行无法正常工作,实际上我收到此错误:
System.ArgumentNullException: '值不能为空。参数名称:key'
如果我将 ID 从 int? 更改为 int,则上述代码有效。
对于可为空类型的键,临时(负)Id 似乎不会分配给 Id。
Nullable-type键有一些优点,主要是在Save阶段不显示看似懒惰生成的临时Id。
如果这是一个受支持的功能并且我看到的是一个错误,或者更确切地说这只是一个不受支持的功能,我在文档中找不到,我应该避免使用可空类型的主键。
【问题讨论】:
-
你为什么要添加然后删除?
-
对比
0而不是null有什么问题? -
如果您不想保留更改,请不要致电
SaveChanges。确保在using块中也使用 DbContext - 它的生命周期很短,仅用于工作单元。如果您不调用SaveChanges(),则所有修改都将在 DbContext 被释放时被丢弃 -
所有这些都是设计使然,你不想要一个 int 吗?代码中的 id 除非您的数据库也允许 null(并且在您编写时,它不允许)
-
BTW Id 不应该可以为空。表的 PK 不能为空。如果您想使用自动生成的 ID,只需保留其默认值 0。当 ID 为 0 时,EF Core(以及所有 ORM)将生成一个 INSERT,如果它不为零,则更新,除非实体是标记为新而不是修改
标签: c# entity-framework ef-core-2.2