Use IEntityTypeConfiguration with a base entity

后端 未结 4 994
醉梦人生
醉梦人生 2021-02-05 14:40

In EF Core 2.0, we have the ability to derive from IEntityTypeConfiguration for cleaner Fluent API mappings (source).

How can I extend this pattern to utili

4条回答
  •  情歌与酒
    2021-02-05 15:06

    I'm late to the party, but this is what I did in the OnModelCreating method to achieve similar results.

    Basically, I have (4) properties that inherit from a BaseEntity. Two of those are dates why two are strings.

    For the dates, I wanted the default to be SQL's GETUTCDATE and the string to be "SystemGenerated." Using a static helper that allows me to retrieve the property name from BaseEntity in a strongly-typed manner, I grab the (4) property names. Then, I iterate over all of the iterate over all of the ModelBuilder entities after my primary mappings are set-up. This allows modelBuilder.Model.GetEntityTypes to return the entities that the modelBuidler is aware of. Then it's a matter of looking at the ClrType.BaseType to see if the type inherits from my BaseEntity and setting the defaults on the PropertyBuilder.

    I tested this directly and through EF Migrations which confirmed that the proper SQL was generated.

    var createdAtUtc = StaticHelpers.GetPropertyName(x => x.CreatedAtUtc);
    var lastModifiedAtUtc = StaticHelpers.GetPropertyName(x => x.LastModifiedAtUtc);
    var createdBy = StaticHelpers.GetPropertyName(x => x.CreatedBy);
    var lastModifiedBy = StaticHelpers.GetPropertyName(x => x.LastModifiedBy);
    foreach (var t in modelBuilder.Model.GetEntityTypes())
    {
        if (t.ClrType.BaseType == typeof(BaseEntity))
        {
            modelBuilder.Entity(t.ClrType).Property(createdAtUtc).HasDefaultValueSql("GETUTCDATE()");
            modelBuilder.Entity(t.ClrType).Property(lastModifiedAtUtc).HasDefaultValueSql("GETUTCDATE()");
            modelBuilder.Entity(t.ClrType).Property(createdBy).HasDefaultValueSql("SystemGenerated");
            modelBuilder.Entity(t.ClrType).Property(lastModifiedBy).HasDefaultValueSql("SystemGenerated");
        }
    }
    

    Here is the the static helper for getting property names for a given type..

    public static string GetPropertyName(Expression> expression)
    {
        if (expression.Body is MemberExpression)
        {
            return ((MemberExpression)expression.Body).Member.Name;
        }
        else
        {
            var op = ((UnaryExpression)expression.Body).Operand;
            return ((MemberExpression)op).Member.Name;
        }
    }
    

提交回复
热议问题