As far as I know, there is no attribute to specify a default database value (SQL calculated or otherwise) on your entity property, instead you need to add the information to your "OnModelCreating" method of your DbContext class and it'll use that info for the migration. You'll find there are many powerful things you can do OnModelCreating that you can't do with attributes...
Here are two sets of examples, one for EF 6, one for EF Core.
Single entity property configuration in EF 6
public class MyDbContext : Microsoft.EntityFrameworkCore.DbContext
{
protected override void OnModelCreating(DbModelBuilder builder)
{
base.OnModelCreating(builder);
modelBuilder.Entity<MyInheritedEntityType>()
.Property(p => p.PerformedOn)
.HasColumnAnnotation("SqlDefaultValue", "getDate()");
}
}
To do this for ALL entities inheriting from BaseSchema
in EF 6, there are three steps:
- Create an attribute to flag the property needing to be configured in your base class:
/// <summary>
/// Simply an empty attribute that specifies the field should be defaulted to GetDate() in DB.
/// </summary>
[System.AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
class DefaultToNowAttribute: Attribute
{
}
- Apply the attribute to any
DateTime
properties (including in base classes) you want to default to GetDate()
class BaseSchema
{
[Key]
[ScaffoldColumn(false)]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public bool IsDeleted { get; set; }
[DefaultToNow]
public DateTime PerformedOn { get; set; }
}
- Use the following in
OnModelCreating
:
modelBuilder.Properties<DateTime>()
.Where(x => x.CustomAttributes.Any(y => y.AttributeType == typeof(DefaultToNowAttribute)))
.Configure(x => x.HasColumnAnnotation("SqlDefaultValue", "getDate()"));
Single Entity Example in EF Core 5:
public class MyDbContext : Microsoft.EntityFrameworkCore.DbContext
{
protected override void OnModelCreating(DbModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<HoodAudits>(ha =>
ha.Property(p => p.PerformedOn).HasDefaultValueSql("GETDATE()"));
}
}
To do this for ALL entities inheriting from BaseSchema
in EF Core 5 you can use the following in OnModelCreating
:
var contextType = typeof(MyDbContext);
// A really involved reflection query
foreach (var inerhitsFromBaseSchema in
System.Reflection.Assembly.GetExecutingAssembly().GetTypes()
.Where(x => typeof(BaseSchema).IsAssignableFrom(x) // Inherits BaseSchema
&& contextType.FindMembers( // And is a DbSet<> in the context
System.Reflection.MemberTypes.Property,
System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance,
(y, z) =>
((System.Reflection.PropertyInfo)y).GetGetMethod().ReturnType.IsGenericType
&& ((System.Reflection.PropertyInfo)y).GetGetMethod().ReturnType.GetGenericTypeDefinition() == typeof(DbSet<>)
&& ((System.Reflection.PropertyInfo)y).GetGetMethod().ReturnType.GetGenericArguments()[0] == x,
null).Length > 0)) // End And is a DbSet<> in the context
// To run one line against each found object.
builder.Entity(inheritsFromBaseSchema).Property("PerformedOn")
.HasDefaultValueSql("GETDATE()");