0

背景:

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

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。

问题:

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

最后注:

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

任何想法,任何人?

4

2 回答 2

1

出于性能原因缓存模型。

以下摘录解释了正在发生的事情

模型缓存

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

此文本还提到了一个名为的属性CacheForContextType,但这并没有包含在 EF5 的最终版本中。

这第二个链接提供了一线希望,但又是在 EF5 最终版本之前的日期

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

我们推荐的模式是为您要使用的每个模型在外部创建一个 ModelBuilder -> DbDatabaseMapping -> DbModel。DbModel 应该被缓存并用于创建上下文实例。ModelBuilder -> DbModel 工作流程有点混乱,类名也不是很好,它们将被整理以用于 RTM。

就个人而言,我认为您将不得不找到一种预先了解所有模型的方法...

于 2013-06-26T10:49:21.983 回答
0

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

public DbContext(string nameOrConnectionString, DbCompiledModel model);

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

于 2013-07-02T12:39:59.623 回答