我正在使用 EF Core 6 Code First 方法。当我使用 required 字段定义新实体时,EF 迁移会为此 always 创建一个空的默认约束,如下所示:
migrationBuilder.AlterColumn<Guid>(
name: "TenantId",
table: "Sites",
type: "uniqueidentifier",
nullable: false,
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"), // unnecessary default constraint
oldClrType: typeof(Guid),
oldType: "uniqueidentifier",
oldNullable: true);
在大多数情况下,我不想有任何默认值。我尝试使用这样的模型配置来禁用此行为,但没有效果:
builder.Property(cc => cc.TenantId).HasDefaultValue(null);
builder.Property(cc => cc.TenantId).HasDefaultValueSql(null);
我使用此命令来生成迁移:
dotnet ef migrations add --context:DataContext --project "xxx" xxxx
对于这个特定问题,我找不到任何关于SO的问题,但是有很多类似的问题导致一个答案:只需手动更新生成的脚本。
这对我来说感觉很奇怪。到目前为止,我从未手动更新过脚本,我认为手动更新脚本会导致代码和数据库模式之间的差异。如果手动更改脚本是可行的方法,您能否解释一下为什么这不是问题以及为什么我不应该担心?
非常感谢!
其他详细信息:
// Nullable types are not enabled
public class Site
{
public Tenant Tenant { get; set; }
public Guid TenantId { get; set; }
public Guid Id { get; set; }
...
}
public class Tenant
{
public Guid Id { get; set; }
...
}
public class SiteEntityTypeConfiguration : IEntityTypeConfiguration<Site>
{
public void Configure(EntityTypeBuilder<Site> builder)
{
builder.HasOne(cc => cc.Tenant)
.WithMany()
.OnDelete(DeleteBehavior.Restrict);
}
}
嗯......你不应该担心,但也许你应该担心。
您不应该担心手动更改脚本,因为它不会真正影响运行时行为。默认值仅影响 SQL 端,而不影响 POCO 端。
换句话说,如果您创建 POCO 的新实例,则数据库中具有(或不具有)的任何默认约束都不会影响该新 POCO 实例中的值。
但是,您应该从代码维护的角度担心它,这就是为什么我来到这个线程也是为了寻找一种方法来防止创建默认约束。如果我们有办法做到这一点,我们可以让我们的代码为其他开发人员和我们自己进行自我记录,当我们查看它并询问“为什么此列没有默认约束而其他所有列都有?”时。
我认为这个想法是允许数据库迁移。也就是说,能够增量更新实时数据库。这意味着新列必须有默认值,否则如果表中有任何数据,您将无法应用添加列的迁移。 (新列需要现有行的值源。)
请注意,如果是新建表,而不是向现有表添加新列,则该列不会获得默认值说明符,除非您添加一个。
您不能让 [Required] 属性具有空默认值。这将违反约束。
如果需要某个属性,它将在数据库中标记为 NON NULLable。所以你不能使用 null 作为默认值。