代码首先为必填字段生成可为空的列
Posted
技术标签:
【中文标题】代码首先为必填字段生成可为空的列【英文标题】:Code first generate nullable columns for Required fileds 【发布时间】:2021-12-25 02:03:10 【问题描述】:我有下一个 C# 代码第一类字段定义(.NET 5):
[Required]
public Visa Visa get; set;
[Required]
public Embassy Embassy get; set;
尽管需要属性 EF 生成可为空的 DB 列:
VisaId = table.Column<int>(type: "int", nullable: true),
EmbassyId = table.Column<int>(type: "int", nullable: true),
如何解决这个问题并使其不为空?在其他类中类似的代码,它按预期工作。
感谢您的帮助!
【问题讨论】:
这里没有显示任何流畅的配置?还是显式可为空的 FK 属性(如public int? VisaId get; set;
)?
嗨,Ivan,在快照中我得到的只是: b.PropertyRemove-Migration
和Add-Migration
?
嗨伊万。是的,我做到了。尝试删除并重新添加迁移。现在为 VS 安装更新 :)
【参考方案1】:
如果您没有在实体中指定外键,EFCore 将生成一个默认可以为空的影子属性(正如您目前在 .NET 5 中看到的那样)。
如果您继续使用 .NET 5,有几种方法可以为您的实体生成不可为空的列。
我们可以显式地创建外键属性。
public int VisaId get; set;
public Visa Visa get; set;
或者您可以在 DbContext 中流畅地指定它并使用IsRequired()
。
public class MyContext : DbContext
public DbSet<MyEntity> MyEntities get; set;
public DbSet<Visa> Visas get; set;
protected override void OnModelCreating(ModelBuilder modelBuilder)
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<MyEntity>().Property<int>("VisaId").IsRequired();
如果您没有卡在 .NET 5 上并且可以迁移到 .NET 6,EFCore 是完全 NRT 注释的,并且会像这样进行迁移。将<Nullable>enable<Nullable>
添加到您的项目文件或在实体文件的顶部添加#nullable enable
。重新生成迁移,您应该会看到自动生成的列不可为空。
更新:
我进行了更多调查,以尝试重新创建您的原始情况,即您的原始类确实有一些不可为空的列。
[Required]
注释似乎真的依赖于目标框架和您正在使用的 EFCore 版本。
这是我的示例类
public class MyContext : DbContext
public DbSet<Country> Countries get; set;
public DbSet<Visa> Visas get; set;
public DbSet<Person> Persons get; set;
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
optionsBuilder.UseSqlServer("this is one bad connectiong string");
public class Country
public int Id get; set;
public class Visa
public int Id get; set;
public class Person
public int Id get; set;
[Required]
public Visa Visa get; set;
public Country Country get; set;
我正在使用 SDK 风格的控制台应用程序来生成迁移。
在以下框架和 efcore 版本的所有中,启用Nullable Contexts 会使生成的列具有带注释的可空性。这是 IMO 最简单的修复方法。
使用net48
、netcoreapp3.1
、net5.0
或net6.0
和EFCore 3.1.21,Required
注解确实有效果。
相关生成表:
migrationBuilder.CreateTable(
name: "Persons",
columns: table => new
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
VisaId = table.Column<int>(nullable: false),
CountryId = table.Column<int>(nullable: true)
,
我只是更新 TFM 和 EFCore 版本,删除现有迁移并重新生成它们。 这是我以表格形式总结的发现
TFM | EFCore | nullable: VisaId | nullable: CountryId |
---|---|---|---|
net48, netcoreapp3.1, net5.0, net6.0 | 3.1.21 | false | true |
netcoreapp3.1, net5.0, net6.0 | 5.0.12 | true | true |
net6.0 | 6.0.0 | false | true |
希望这有助于澄清您的情况!
【讨论】:
奇怪的是,在我的相邻班级中,我有:` [必需] public Country Country get;放; ` 它会生成: ` migrationBuilder.AddColumnRequired
注释实际上确实使列不可为空,而无需手动指定 shadow 属性。
@smatveev 检查我的更新。我想你可能会发现它很有用。
感谢汉克的更新。太棒了!这正是我正在处理的问题以上是关于代码首先为必填字段生成可为空的列的主要内容,如果未能解决你的问题,请参考以下文章