如何在Entity Framework Core 2.0中使用模型内部的OnModelCreating?

Dre*_*pin 2 c# model entity-framework-core

我对Entity Framework很新,所以对我来说很容易,但是我想让我的模型更流畅的API更接近使用,并把它放在模型对象本身.我在文档中找不到任何内容,或者通过Google搜索内置的方法来执行此操作,所以我想也许我可以在模型上调用静态方法(如果它存在于DbContext.OnModelCreating()方法中).这是我想出的,但它似乎没有工作,每当我跑Add-Migration,并且Script-Migration,即使我首先删除所有迁移.知道我在哪里出错吗?或者更好的方法呢?

Trademark.cs(模型)

public class Trademark
{
    public string Name { get; set; }
    // ... 
    protected static void OnModelCreating( ModelBuilder modelBuilder )
    {
        modelBuilder.Entity<Trademark>().HasIndex(x=>x.Name).IsUnique();
    }
}
Run Code Online (Sandbox Code Playgroud)

PartDbContext.cs(DbContext)

public class PartDbContext: DbContext
{
    // ...
    public DbSet<Trademark> Trademarks { get; set; }
    public PartDbContext( DbContextOptions options ): base(options)
    {
    }
    protected override void OnModelCreating( ModelBuilder modelBuilder )
    {
        dynamic m = modelBuilder.Model.GetType().GetMethod("OnModelCreating",System.Reflection.BindingFlags.Static);
        if( m != null )
            m.OnModelCreating(modelBuilder);
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为问题在于modelBuilder.Model.GetType()回报typeof(IMutableModel)而不是typeof(Trademark).所以,也许我只需要知道如何从中获得模型的模型类型modelBuilder.

注:如果我把modelBuilder.Entity<Trademark>().HasIndex(x => x.Name).IsUnique();里面PartDbContext.OnModelCreating(),加入了独特的约束.所以,我知道我至少得到了正确的答案.


UPDATE

对于其他任何有兴趣这样做的人,我决定将使用量缩小一点,只传递EntityTypeBuilder而不是整体ModelBuilder.

PartDbContext.cs

protected override void OnModelCreating( ModelBuilder modelBuilder )
{
    foreach( var entityType in modelBuilder.Model.GetEntityTypes() )
    {
        var method = entityType.ClrType.GetMethod("OnEntityCreating",BindingFlags.Static|BindingFlags.NonPublic);
        if( method != null )
        {
            var entityBuilder = new object[] {
                typeof(ModelBuilder)
                .GetMethod("Entity",new Type[]{})
                .MakeGenericMethod(entityType.ClrType)
                .Invoke(modelBuilder,null)
            };
            method.Invoke(null,entityBuilder);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Trademark.cs

public class Trademark
{
    public string Name { get; set; }
    protected static void OnEntityCreating( EntityTypeBuilder<Trademark> entityBuilder )
    {
        entityBuilder.HasIndex(x=>x.Name).IsUnique();
    }

}
Run Code Online (Sandbox Code Playgroud)

Iva*_*oev 5

您可以迭代所有发现的实体类型,并通过反射调用自定义方法(如果已定义):

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    var parameters = new object[] { modelBuilder };
    foreach (var entityType in modelBuilder.Model.GetEntityTypes())
    {
        var method = entityType.ClrType.GetMethod("OnModelCreating", BindingFlags.Static | BindingFlags.NonPublic);
        if (method != null)
            method.Invoke(null, parameters);
    }
}
Run Code Online (Sandbox Code Playgroud)