Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何减少OnModelCreating中fluentapi的代码_C#_Asp.net Core 2.1_Entity Framework Core 2.1 - Fatal编程技术网

C# 如何减少OnModelCreating中fluentapi的代码

C# 如何减少OnModelCreating中fluentapi的代码,c#,asp.net-core-2.1,entity-framework-core-2.1,C#,Asp.net Core 2.1,Entity Framework Core 2.1,我的表中有几个列不应该在以后的任何更新中更改,因此我在OnModelCreating中创建了fluent API,如下所示 base.OnModelCreating(builder); builder.Entity<UserSetting>() .Property(p => p.ID) .Metadata.AfterSaveBehavior = PropertySaveBehavior.Ignore; builder

我的表中有几个列不应该在以后的任何更新中更改,因此我在
OnModelCreating
中创建了fluent API,如下所示

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;

考虑到DRY,我建议您创建自己的扩展方法,如下所示:

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;
    }
}
公共静态类扩展方法
{
MutableCollumn(此ModelBuilder ModelBuilder,Expression propertyExpression)中的公共静态void,其中tenty:class
{
modelBuilder.Entity()
.Property(propertyExpression)
.Metadata.AfterSaveBehavior=PropertySaveBhavior.Ignore;
}
}
那么你可以称之为:

modelBuilder.InmutableCollumn<UserSetting, Guid>(p => p.Id);
modelBuilder.inmutablecolumn(p=>p.Id);
这将使您的代码更易于维护,并且减少重复性

您甚至可以让该方法接收表达式列表,只需要找到一种处理属性类型的方法。看看这个草案:

    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;
    }
mutableCollumn(此ModelBuilder ModelBuilder,参数表达式[]propertiesExpression)中的公共静态void,其中TEntity:class
{
foreach(PropertieExpression中的var propertyExpression)
modelBuilder.Entity()
.Property(propertyExpression)
.Metadata.AfterSaveBehavior=PropertySaveBhavior.Ignore;
}
所以它会被这样称呼:

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

有很多方法可以做到这一点,最自然的方法是在实现
IEntityTypeConfiguration的受约束泛型类中移动公共代码。然后迭代模型实体类型,通过反射实例化配置类,并动态调用
ModelBuilder
ApplyConfiguration
方法(或使用反射)

例如,配置类:

public class CommonEntityTypeConfiguration<TEntity> : IEntityTypeConfiguration<TEntity>
    where TEntity : Common
{
    public void Configure(EntityTypeBuilder<TEntity> builder)
    {
        builder.Property(p => p.ID)
            .Metadata.AfterSaveBehavior = PropertySaveBehavior.Ignore;
        builder.Property(p => p.CreatedOn)
            .Metadata.AfterSaveBehavior = PropertySaveBehavior.Ignore;
        builder.Property(p => p.CreatedBy)
            .Metadata.AfterSaveBehavior = PropertySaveBehavior.Ignore;
    }
}

这使您能够流畅地配置基类的所有方面,而不仅仅是某些属性的
AfterSaveBehavior

所有这些表都共享基类或接口吗?是的,所有模型类都来自一个基类。您能在问题中包括该类吗?我猜您希望将上述配置应用于继承该基类的所有类,对吗?使用泛型方法将此繁琐的代码转换为简单方法callMy Qestion更新为基类。引发了一个Un-Handlec异常“Configure(Microsoft.EntityFrameworkCore.Metadata.Builders.EntityTypeBuilder)“无法从用法推断。请尝试显式指定类型参数。”@Ramesh抱歉,忘记了非泛型
Entity
方法没有返回泛型
EntityTypeBuilder
。现在正在工作(已测试:)
public class CommonEntityTypeConfiguration<TEntity> : IEntityTypeConfiguration<TEntity>
    where TEntity : Common
{
    public void Configure(EntityTypeBuilder<TEntity> builder)
    {
        builder.Property(p => p.ID)
            .Metadata.AfterSaveBehavior = PropertySaveBehavior.Ignore;
        builder.Property(p => p.CreatedOn)
            .Metadata.AfterSaveBehavior = PropertySaveBehavior.Ignore;
        builder.Property(p => p.CreatedBy)
            .Metadata.AfterSaveBehavior = PropertySaveBehavior.Ignore;
    }
}
var entityTypes = modelBuilder.Model.GetEntityTypes()
    .Where(t => typeof(Common).IsAssignableFrom(t.ClrType));
foreach (var entityType in entityTypes)
{
    var configurationType = typeof(CommonEntityTypeConfiguration<>)
        .MakeGenericType(entityType.ClrType);
    modelBuilder.ApplyConfiguration(
        (dynamic)Activator.CreateInstance(configurationType));
}