如何强制触发OnModelCreating每个初始化的DataContext

时间:2017-09-04 10:37:26

标签: c# entity-framework-6 unit-of-work .net-framework-version

我想解雇OnModelCreating每new DataContext(new Entity()) ... 但是当我创建一个表的连接时,它的工作原理。当为另一个表创建连接时,OnModelCreating不再起作用,因为我得到了错误,

the entity type <tableName> is not part of the model for the current context.

public class DataContext : DbContext
{
    private BaseEntity _entity;

    public DataContext(BaseEntity entity)
    {
        Database.Connection.ConnectionString = Parameters.ConnectionString;

        _entity = entity;
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        _entity.Map(modelBuilder); // this is dynamic fluent api here
    }
}

2 个答案:

答案 0 :(得分:1)

ta.speot.is是正确的,因为对ModelBuilder进行了缓存,OnModelCreating仅触发一次。 有几种情况需要再次执行OnModelCreating。例如,当跨会话实施多租户时,可能需要再次触发OnModelCreating。

首次创建modelBuilder时,EF将其缓存以提高性能。使用IDbModelCacheKeyProvider.CacheKey对其进行缓存。当找不到与CacheKey关联的Cache时,将触发OnModelCreating。因此,要再次触发OnModelCreating,必须更改IDbModelCacheKeyProvider.CacheKey。

要更改缓存键,DbContext类必须实现IDbModelCacheKeyProvider。在IDbModelCacheKeyProvider的CacheKey属性中返回新的缓存键时,将再次触发OnModelCreating事件。

例如,请参见以下代码块:

public class TenantContext : DbContext, IDbModelCacheKeyProvider
{
    string IDbModelCacheKeyProvider.CacheKey {
        get { return tenentID.ToString(); }
    }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
    }
}

更改tenantID后,它会强制执行OnModelCreating,因为新的tenantID可能无法使用缓存。

注意:仅在非常紧急时才应更改CacheKey。频繁更改CacheKey会降低性能。

答案 1 :(得分:0)

手册已经涵盖了你!

  

DbContext.OnModelCreating Method (DbModelBuilder)

     

...

     

<强>说明

     

通常,只有在创建派生上下文的第一个实例时才调用此方法一次。然后缓存该上下文的模型,该模型适用于app域中上下文的所有其他实例。可以通过在给定的ModelBuidler [sic]上设置ModelCaching属性来禁用此缓存,但请注意,这会严重降低性能。通过直接使用DbModelBuilder和DbContextFactory类,可以更好地控制缓存。

虽然您可能想要探索DbContext这样的通用public class DataContext<TBaseEntity> : DbContext。这将引导您进入一种架构,其中每DataContext类型有一个TBaseEntity类型。