[英]How Do I Use OnModelCreating Inside the Model itself in Entity Framework Core 2.0?
I'm very new to Entity Framework, so go easy on me, but I would like to keep the fluent API for my models a little closer to usage and put it inside the model object itself. 我是Entity Framework的新手,所以轻松一点,但是我想使模型的流畅API更加接近用法,并将其放在模型对象本身中。 I couldn't find anything in the documentation or via Google search for a built in way to do this, so I thought perhaps I could just call a static method on the model if it exists from the
DbContext.OnModelCreating()
method. 我在文档中找不到任何内容,也无法通过Google搜索找到任何内置方法来执行此操作,因此,我认为如果
DbContext.OnModelCreating()
方法中存在静态方法,那么我也许可以在模型上调用它。 Here's what I come up with, but it doesn't seem to work whenever I run Add-Migration
, and Script-Migration
, even if I remove all migrations first. 这就是我的想法,但是即使我先删除所有迁移,但每次运行
Add-Migration
和Script-Migration
,它似乎都无法正常工作。 Any idea where I'm going wrong on this? 知道我在哪里出错吗? or perhaps a better way to do it?
还是更好的方法呢?
Trademark.cs (the model) Trademark.cs(模型)
public class Trademark
{
public string Name { get; set; }
// ...
protected static void OnModelCreating( ModelBuilder modelBuilder )
{
modelBuilder.Entity<Trademark>().HasIndex(x=>x.Name).IsUnique();
}
}
PartDbContext.cs ( DbContext
) 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);
}
}
I'm thinking the issue is that modelBuilder.Model.GetType()
returns typeof(IMutableModel)
and not typeof(Trademark)
. 我认为问题是
modelBuilder.Model.GetType()
返回typeof(IMutableModel)
而不是typeof(Trademark)
。 So, perhaps I just need to know how to get the type of the model of the model from modelBuilder
. 因此,也许我只需要知道如何从
modelBuilder
获取模型的模型modelBuilder
。
Note: If I put modelBuilder.Entity<Trademark>().HasIndex(x => x.Name).IsUnique();
注意:如果我放置
modelBuilder.Entity<Trademark>().HasIndex(x => x.Name).IsUnique();
inside PartDbContext.OnModelCreating()
, the unique constraint is added. 在
PartDbContext.OnModelCreating()
内部,添加了唯一约束。 So, I know I at least got that bit correct. 所以,我知道我至少是正确的。
For anyone else interested in doing this, I decided to narrow the usage down a bit more and only pass the EntityTypeBuilder
instead of the whole ModelBuilder
. 对于对此感兴趣的其他人,我决定将使用范围进一步缩小,只传递
EntityTypeBuilder
而不是整个ModelBuilder
。
PartDbContext.cs 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);
}
}
}
Trademark.cs 商标
public class Trademark
{
public string Name { get; set; }
protected static void OnEntityCreating( EntityTypeBuilder<Trademark> entityBuilder )
{
entityBuilder.HasIndex(x=>x.Name).IsUnique();
}
}
You can iterate all discovered entity types and invoke the custom method (if defined) via reflection: 您可以迭代所有发现的实体类型并通过反射调用自定义方法(如果已定义):
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);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.