如果您没有在实体中指定外键,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 |
希望这有助于澄清您的情况!