实体框架+ Autofac:如何正确地重新加载映射/配置?

时间:2013-06-26 09:09:05

标签: c# .net entity-framework autofac

背景

我们的核心框架从自身,主应用程序和我们使用接口安装的任何模块(下面)加载所有实体框架映射:

public interface IEntityTypeConfiguration : IDependency
{
}

我们在这个核心框架中有一个DbContext,它加载了所有的映射:

public class DefaultDbContext : DbContextBase
    {
        private readonly Lazy<IEnumerable<IEntityTypeConfiguration>> configurations;

        public DefaultDbContext(Lazy<IEnumerable<IEntityTypeConfiguration>> configurations)
            : base()
        {
            this.configurations = configurations;
            Configuration.ProxyCreationEnabled = false;
        }

        public DefaultDbContext(string connectionString, Lazy<IEnumerable<IEntityTypeConfiguration>> configurations)
            : base(connectionString)
        {
            this.configurations = configurations;
            Configuration.ProxyCreationEnabled = false;
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            foreach (dynamic typeConfiguration in configurations.Value)
            {
                modelBuilder.Configurations.Add(typeConfiguration);
            }

            Database.SetInitializer(new CreateTablesIfNotExist<DefaultDbContext>());
        }
    }

所以这样我们就有了一个DbContext。

问题:

我们遇到了一个问题,即当我们动态添加新模块(具有自己的映射)时,即使我们确定DefaultDbContext的新实例已经确定,EF也不会加载这些映射。已创建。因此,EF必须在某处缓存映射。有没有办法清除缓存?

最终注意:

您可能已经猜到,我们正在使用IoC,即Autofac。如果您需要任何进一步的信息,请询问。

任何想法,任何人?

2 个答案:

答案 0 :(得分:1)

出于性能原因缓存模型。

The following excerpt explains what is going on

  

模型缓存

     

发现模型,处理数据注释和应用流畅的API配置需要花费一些成本。为了避免每次实例化派生的DbContext时产生此成本,在第一次初始化期间缓存模型。每次在同一AppDomain中构造相同的派生上下文时,都会重新使用缓存的模型。

本文还提到了一个名为CacheForContextType的属性,但这并没有进入EF5的最终版本。

This second link提供了一线希望,但在EF5的最终版本之前又过时了

  

我们在CTP5中删除了CacheForContextType,我们原本打算在人们想要在具有不同模型的同一AppDomain中使用相同的上下文时使用它。问题是它会在每次初始化时创建模型,并且不允许任何方式缓存一系列模型并选择在每次初始化期间使用哪一个模型。模型创建很昂贵,所以我们想要推广一个更好的模式。

     

我们建议的模式是从外部创建一个模型构建器 - &gt; DbDatabaseMapping - &gt;要使用的每个模型的DbModel。应该缓存DbModel并将其用于创建上下文实例。 ModelBuilder - &gt; DbModel的工作流程有点乱,类名不是很好,它们将被整理为RTM。

就我个人而言,我认为你必须先找到一种了解所有模型的方法......

答案 1 :(得分:0)

解决!我们在DbContext类上找到了这个构造函数:

public DbContext(string nameOrConnectionString, DbCompiledModel model);

我不能在这里分享所有代码,但基本上我们正在创建一个新的DbCompiledModel并在必要时传递它。