Search code examples
c#asp.net-core-2.1entity-framework-core-2.1

How to reduce the code at fluent API in OnModelCreating


I have few columns that are not supposed to change by any future update in the table so I have made my fluent API in OnModelCreating as follows.

base.OnModelCreating(builder);

builder.Entity<UserSetting>()
              .Property(p => p.ID)
                .Metadata.AfterSaveBehavior = PropertySaveBehavior.Ignore;
builder.Entity<UserSetting>()
              .Property(p => p.CreatedOn)
                .Metadata.AfterSaveBehavior = PropertySaveBehavior.Ignore;
builder.Entity<UserSetting>()
              .Property(p => p.CreatedBy)
                .Metadata.AfterSaveBehavior = PropertySaveBehavior.Ignore;

I have 40 tables in my project so I have written 120 lines in this method.

Instead of writing 120 lines, Is there any easier way to achieve this.?

Update: Here is my base class that inherited by all other classes.

public class Common
{        
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }        
    [DataType(DataType.DateTime)]
    public DateTime CreatedOn { get; set; } = System.DateTime.Now;
    public string CreatedBy { get; set; }       
    [DataType(DataType.DateTime)]
    public DateTime LastUpdatedOn { get; set; }  = System.DateTime.Now;        
    public string LastUpdatedBy { get; set; }
    public string Remarks { get; set; }
}

public class table1 : Common
{
    //Other Properties...
}

Solution

  • Having DRY in mind, I would suggestion you to create your own extension method, like so:

    public static class ExtensionMethod
    {
        public static void InmutableCollumn<TEntity, TProperty>(this ModelBuilder modelBuilder, Expression<Func<TEntity, TProperty>> propertyExpression) where TEntity : class
        {
    
            modelBuilder.Entity<TEntity>()
              .Property(propertyExpression)
                .Metadata.AfterSaveBehavior = PropertySaveBehavior.Ignore;
        }
    }
    

    Then you would call it:

    modelBuilder.InmutableCollumn<UserSetting, Guid>(p => p.Id);
    

    That would make your code easier to maintain and a bit less repetitive.

    You could even make the method receive a list of expressions, just need to find a way to deal with the property type. Look at this draft:

        public static void InmutableCollumn<TEntity>(this ModelBuilder modelBuilder, params Expression<Func<TEntity, object>>[] propertiesExpression) where TEntity : class
        {
            foreach(var propertyExpression in propertiesExpression)
                modelBuilder.Entity<TEntity>()
                    .Property(propertyExpression)
                    .Metadata.AfterSaveBehavior = PropertySaveBehavior.Ignore;
        }
    

    So it would be call like this:

    modelBuilder.InmutableCollumn<UserSetting>(p => p.ID, p => p.CreatedOn);