40

In a legacy app, most string properties can't be null and need to have a default value of string.empty.

I know it's possible to do this with migrations, but I'm looking for a way to do this using the fluent configuration interface:

    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.
            }
    }

Is there any way to do this or I'm doomed to initialize all strings in the entity constructors?

CB-Dan
  • 1,718
  • 2
  • 16
  • 29
  • How about setting it in the entity constructor? – Old Geezer Feb 10 '15 at 03:18
  • @old-geezer, I'm working through this issue right now, it doesn't solve the issue for me. – Mason240 Apr 02 '15 at 17:33
  • Just as an addition: Since it's not possible with the EF 6 and I did not want to set the default value in the constructor, I set the default constraints using SQL, at least for unit tests that use model first. This happens all the time after I create the DBContext instance, but it's a workaround for unit tests at least. – Jürgen Bayer Nov 21 '16 at 22:06

6 Answers6

54

Unfortunately the answer right now is 'No'.

But you can vote for Better support for default values

EDIT 30 Mar 2015: It's coming in EF7... Support database default values in Code First

EDIT 30 Jan 2017: General support for default database values is part of EF Core (the new name for EF7)... Default values

EDIT 17 Jan 2018: I'm not sure why people are commenting that EF7 is still a "pipe dream". EF7 (renamed EF Core) was released on 27th June 2016 and supports the setting of default values in Code First using the FluentAPI like this:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.Rating)
        .HasDefaultValue(3);
}

EF Core 2.0 was released on 14 August 2017

Colin
  • 22,328
  • 17
  • 103
  • 197
  • 6
    EF7 is a pipe dream and not usable for production. We need this in EF6 now! – Dave Mar 21 '16 at 21:58
  • @Sabre why is it not usable? What problem are you having? – Colin Mar 01 '18 at 10:17
  • 3
    @Colin The EF Core team themselves acknowledge that there are quite a few features missing before it can replace EF6 as the "recommended version": https://github.com/aspnet/EntityFrameworkCore/wiki/roadmap – Sabre Mar 01 '18 at 13:43
  • 1
    I'm astounded. EF has been around for 10 years. The most basic thing I do when designing a database is set default values. This feature should've been present from version 1, 10 years ago. Instead the EF team spend all their time trying to make EF an all singing all dancing answer to the riddle of the universe; and, of course, fail at it. No fit for purpose. – user1040323 Oct 11 '18 at 14:26
  • @user1040323 agreed. Default values missing from EF(not-core) is kinda silly. EF core is still missing significant features, oh like `SqlQuery` which itself is kinda silly. So we're stuck between EF and EF core. Sigh. – enorl76 Feb 03 '19 at 18:07
  • is there any way to chain these for when you have multiple properties of the same entity that needs to be set? Seems goofy to create a bunch of these for the same entity. – Post Impatica Jul 18 '19 at 20:05
  • And how can you give the Default Constraint the name "DF_Blog_Rating"? modelBuilder.Entityy() .Property(b => b.Rating) .HasDefaultValue(3).HasConstraintName("DF_Blog_Rating"); doesn't work. – user1531040 Mar 01 '21 at 09:49
22

Now the answer is Yes:

AddColumn("[table name]", 
          "[column name]", 
          c => c.Boolean(nullable: false, defaultValue: false));
Community
  • 1
  • 1
Gh61
  • 9,222
  • 4
  • 28
  • 39
  • 2
    Thanks. We ended up switching to NHibernate instead, but hopefully this answer will help other people. – CB-Dan Mar 18 '15 at 00:22
  • 47
    How come the `DbMigration.AddColumn` method is marked as the answer when the question says "I know it's possible to do this with migrations, but I'm looking for a way to do this using the fluent configuration interface" ? – Colin Mar 30 '15 at 09:12
  • 8
    Agreed. This answer does not answer the question. – Stephen Holt Sep 28 '15 at 11:19
  • 3
    I agree, it should not be selected as answer. But maybe it can help other people. I don't know if answer could be unselected. Better answer for now is @Colin's – Gh61 Jan 02 '17 at 12:47
7

You can set the default value within the constructor

class Foo : Model
{
    public bool DefaultBool { get; set; }

    public Foo()
    {
        DefaultBool = true;
    }
}

When you create a new Foo it will set the true value for the property DefaultBool. This is not a default constraint but it works.

Ariel Moraes
  • 602
  • 7
  • 15
  • 3
    This doesn't answer the question at all. OP and others (myself included) came here to find out how to set the default constraint on the table. – async Sep 10 '16 at 18:17
  • 1
    Only EF7 will support default constraint, that why I answered using this pattern. This is a workaround when using prior EF versions. By the way, I said "this is not a default constraint". – Ariel Moraes Sep 10 '16 at 18:42
1

This is my answer to this question. In ef Core 3.1+ you can define an extention methode like this :

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);
        }
    }

Then you can use this extention methode in this way :

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()" );

    }
}

All Entities with the property 'Version' default value set to 0 and also all Entities with the property 'CreateDate' default value set to current DateTime .

Please vote up if it helps.

Ali Mahmoodi
  • 858
  • 10
  • 14
-2

I found 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; }
    }
}
Community
  • 1
  • 1
Demodave
  • 6,242
  • 6
  • 43
  • 58
-6

I found that just using Auto-Property Initializer on entity property is enough to get the job done.

For example:

public class Thing {
    public bool IsBigThing{ get; set; } = false;
}
Velyo
  • 262
  • 1
  • 8