use*_*298 39 c# asp.net-mvc entity-framework
我是EF新手,所以这里.我有一个包含以下内容的类
public class EmailTemplate
{
public Guid Id { get; set; }
[MaxLength(2000)]
public string Html { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这是我的映射类
class EmailMapper : EntityTypeConfiguration<EmailTemplate>
{
public EmailMapper()
{
ToTable("EmailTemplate");
HasKey(c => c.Id);
Property(c => c.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(c => c.Id).IsRequired();
}
}
Run Code Online (Sandbox Code Playgroud)
我想打电话DbContext.SaveChanges()
,但是我收到以下错误:
异常详细信息:System.Data.SqlClient.SqlException:无法将值NULL插入列'Id',表'AutoSendConnection.dbo.EmailTemplates'; 列不允许空值.INSERT失败.
我究竟做错了什么?为什么EF auto不会创建一个独特的GUID?
Mar*_*ark 53
只需在EmailTemplate类上装饰Id字段,如下所示,SQL Server将自动生成插入值.
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public Guid Id { get; set; }
Run Code Online (Sandbox Code Playgroud)
您也可以删除不再需要的Mapper类.
Moh*_*reh 21
使用流畅的API
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Node>().Property(x => x.ID).HasDefaultValueSql("NEWID()");
}
Run Code Online (Sandbox Code Playgroud)
War*_*War 18
在此处解决其他答案
这些其他选项似乎都不起作用,我一次又一次地与 EF 团队在 github 上提出质疑......
https://github.com/aspnet/EntityFramework6/issues/762
...出于某种原因,EF 开发团队似乎认为这是“按设计工作”并反复关闭质疑此“错误”的票证。
EF团队解释
出于某种原因,他们似乎认为“在 SQL 中生成 Guid 被认为不是最佳实践,为了确保密钥立即可用,我们应该在应用程序代码中生成密钥”。
当然,这里的问题是高度填充的表会冒着采取进一步业务操作的风险,使用无效的密钥。
在我的情况下,这可能会破坏一些极其复杂的多服务器 DTC 事务,所以我不相信 MS 的建议是正确的,即 EF Core 目前根本不支持分布式事务,因此在重点关注的上下文中,他们可能有一点.
我的答案(实际上有效)
简而言之,我通过在生成迁移后“手动破解”生成的迁移来解决这个问题......
引用另一个问题的答案如下:
像通常将两个属性放在键属性上一样生成迁移脚本,如下所示...
public class Foo
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
...声明性地说,实体现在是正确的。
它将生成的迁移看起来像:
CreateTable(
"dbo.Foos",
c => new
{
Id = c.Guid(nullable: false),
...
})
.PrimaryKey(t => t.Id)
...;
Run Code Online (Sandbox Code Playgroud)
...我无法确定原因,但在某些情况下这会起作用,而在其他情况下则不会(运行迁移,执行插入以进行测试)。
如果失败,请回滚迁移然后修改它以读取类似...
CreateTable(
"dbo.Foos",
c => new
{
Id = c.Guid(nullable: false, defaultValueSql: "newid()"),
...
})
.PrimaryKey(t => t.Id)
...;
Run Code Online (Sandbox Code Playgroud)
...这里的额外代码告诉 SQL 按照我们的预期生成密钥。
根据经验,出于一致性原因,我会一直应用此更改,这意味着一目了然,您的迁移将准确显示数据库生成了哪些键,当然哪些不是。
经过长时间的调查,我发现在 EF Core 3.1 中你需要使用
builder.Property(e => e.Id).ValueGeneratedOnAdd();
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
51141 次 |
最近记录: |