【问题标题】:How can set a default value constraint with Entity Framework 6 Code First?如何使用 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 实例后,这一直发生,但它至少是单元测试的一种解决方法。

标签: c# .net entity-framework ef-code-first entity-framework-6


【解决方案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;
      }
      

      【讨论】:

        猜你喜欢
        • 2013-11-02
        • 1970-01-01
        • 1970-01-01
        • 2015-01-06
        • 2015-06-07
        • 2011-11-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多