如何使用 Entity Framework 6 Code First 设置默认值约束?

Posted

技术标签:

【中文标题】如何使用 Entity Framework 6 Code First 设置默认值约束?【英文标题】:How can set a default value constraint with Entity Framework 6 Code First? 【发布时间】:2013-12-06 20:09:38 【问题描述】:

在旧版应用程序中,大多数字符串属性不能为空,并且需要具有默认值 string.empty。

我知道可以通过迁移来做到这一点,但我正在寻找一种使用流畅的配置界面来做到这一点的方法:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    
        modelBuilder.Properties<string>().Configure(c =>
        
            c.HasMaxLength(255);

            if (!c.ClrPropertyInfo.IsDefined(typeof (NullableAttribute), false))
            
                c.IsRequired();
                // I want to set a default value (string.empty) here.
            
    

有没有办法做到这一点,或者我注定要初始化实体构造函数中的所有字符串?

【问题讨论】:

在实体构造函数中设置如何? @old-geezer,我现在正在解决这个问题,它并不能解决我的问题。 作为补充:由于 EF 6 无法实现并且我不想在构造函数中设置默认值,因此我使用 SQL 设置默认约束,至少对于使用先做模型。在我创建 DBContext 实例后,这一直发生,但它至少是单元测试的一种解决方法。 【参考方案1】:

很遗憾,现在的答案是“不”。

但你可以投票给Better support for default values

2015 年 3 月 30 日编辑: 它即将在 EF7 中出现...Support database default values in Code First

2017 年 1 月 30 日编辑: 对默认数据库值的一般支持是 EF Core(EF7 的新名称)的一部分...Default values

编辑 2018 年 1 月 17 日:我不知道为什么人们评论说 EF7 仍然是一个“白日梦”。 EF7(更名为 EF Core)于 2016 年 6 月 27 日发布,支持在 Code First 中使用 FluentAPI 设置默认值,如下所示:

protected override void OnModelCreating(ModelBuilder modelBuilder)

    modelBuilder.Entity<Blog>()
        .Property(b => b.Rating)
        .HasDefaultValue(3);

EF Core 2.0 于 2017 年 8 月 14 日发布

【讨论】:

EF7 是白日梦,不能用于生产。我们现在需要在 EF6 中使用它! @Sabre 为什么它不可用?你有什么问题? @Colin EF Core 团队自己承认,在将 EF6 替换为“推荐版本”之前,还缺少很多功能:github.com/aspnet/EntityFrameworkCore/wiki/roadmap 我很震惊。 EF 已经存在 10 年了。我在设计数据库时做的最基本的事情就是设置默认值。这个功能应该在 10 年前的版本 1 中就已经存在。相反,EF 团队把所有的时间都花在了试图让 EF 成为一个能歌善舞的宇宙之谜的答案。当然,失败了。不适合目的。 @user1040323 同意。 EF(非核心)中缺少的默认值有点傻。 EF 核心仍然缺少重要的功能,哦,就像 SqlQuery&lt;T&gt; 本身有点傻。所以我们被困在 EF 和 EF 核心之间。叹息。【参考方案2】:

现在答案是Yes:

AddColumn("[table name]", 
          "[column name]", 
          c => c.Boolean(nullable: false, defaultValue: false));

【讨论】:

谢谢。我们最终改用 NHibernate,但希望这个答案对其他人有所帮助。 为什么DbMigration.AddColumn 方法被标记为答案,当问题说“我知道可以通过迁移来做到这一点,但我正在寻找一种使用流利配置来做到这一点的方法界面”? 同意。这个答案没有回答问题。 我同意,它不应该被选作答案。但也许它可以帮助其他人。我不知道是否可以取消选择答案。现在更好的答案是@Colin's【参考方案3】:

你可以在构造函数中设置默认值

class Foo : Model

    public bool DefaultBool  get; set; 

    public Foo()
    
        DefaultBool = true;
    

当您创建一个新的Foo 时,它将为属性DefaultBool 设置真实值。这不是默认约束,但它有效。

【讨论】:

这根本不能回答问题。 OP 和其他人(包括我自己)来这里了解如何在表上设置默认约束。 只有 EF7 将支持默认约束,这就是我使用此模式回答的原因。这是使用早期 EF 版本时的一种解决方法。顺便说一句,我说“这不是默认约束”。【参考方案4】:

这是我对这个问题的回答。在 ef Core 3.1+ 中,您可以像这样定义扩展方法:

public static void AddDefaultValueSqlConvention(this ModelBuilder modelBuilder, string propertyName, Type propertyType, string defaultValueSql)
    
        foreach (IMutableEntityType entityType in modelBuilder.Model.GetEntityTypes())
        
            IMutableProperty property = entityType.GetProperties().SingleOrDefault(p => p.Name.Equals(propertyName, StringComparison.OrdinalIgnoreCase));
            if (property != null && property.ClrType == propertyType)
                property.SetDefaultValueSql(defaultValueSql);
        
    

那么你就可以这样使用这个扩展方法了:

public class AppDbContext : DbContext

    public AppDbContext(DbContextOptions options) : base(options)
    
    

    protected override void OnModelCreating(ModelBuilder builder)
    

        base.OnModelCreating(builder);

        builder.AddDefaultValueSqlConvention("Version",typeof (int), "0" );
        builder.AddDefaultValueSqlConvention("CreateDate",typeof (DateTime), "GetDate()" );

    

属性'Version'默认值设置为0的所有实体以及属性'CreateDate'默认值设置的所有实体到当前日期时间

如果有帮助请投票。

【讨论】:

【参考方案5】:

我找到this example here

public class Person 
    private const int DEFAULT_AGE = 18;
    private int _age = DEFAULT_AGE;
    [DefaultValue(DEFAULT_AGE)]
    public int Age 
        get  return _age; 
        set  _age = value; 
    

【讨论】:

【参考方案6】:

我发现仅对实体属性使用 Auto-Property Initializer 就足以完成工作。

例如:

public class Thing 
    public bool IsBigThing get; set;  = false;

【讨论】:

以上是关于如何使用 Entity Framework 6 Code First 设置默认值约束?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Entity Framework 6 Code First 设置默认值约束?

在 Entity Framework 6.1(非核心)中,如何使用 IndexAttribute 来定义聚集索引?

如何使用 Entity Framework 6 从 .Net 应用程序访问雪花数据库

如何在 ASP.NET 5 中将 Entity Framework 6 与 MySQL 一起使用?

如何在 Entity Framework 6 DbContext.Database.BeginTransaction 中配置事务超时?

如何将 Database First Entity Framework 4 升级到 6