在已经处理了具有ObjectContext实例的自定义DatabaseInitializer之后

时间:2014-06-23 09:49:48

标签: c# asp.net-mvc entity-framework autofac dbcontext

我有带上下文的autofac

builder.RegisterType<WebRepositoryContext>().WithParameter("mode", (GlobalVariables.DataBaseMode)).InstancePerLifetimeScope();

切换初始化程序

    private static void InitializeDataStore()
    {
        switch (GlobalVariables.DataBaseMode)
        {
            case DataBaseMode.MsSql:
            {
                Database.SetInitializer(new MigrateDatabaseToLatestVersion<WebRepositoryContext, Repository.Migrations.Configuration>());

                var configuration = new Repository.Migrations.Configuration();
                var migrator = new DbMigrator(configuration);
                if (migrator.GetPendingMigrations().Any())
                    migrator.Update();
            }
                break;
            case DataBaseMode.Postgres:
            {
                Database.SetInitializer(new PostgresInitializer());
            }

                break;
        }
    }

初​​始化

public class PostgresInitializer : IDatabaseInitializer<WebRepositoryContext>
{
    public void InitializeDatabase(WebRepositoryContext context)
    {
        //create database
        var h = new PostgresHelper(context);
        h.Create();

        //seed database
        Seed(context);
    }

    protected virtual void Seed(WebRepositoryContext context)
    {

        var seed = new WebRepositorySeed(context);
       seed.Start();
    }
}

当我尝试在项目中获取数据时,比如Home Controller中的var mainPage = DataContext.MainPage.First();我得到了“ObjectContext实例已经被处理掉了,不能再用于需要连接的操作了。”

public class HomeController : BaseController其中public WebRepositoryContext DataContext { get; set; }

可能是初始化配置上下文,由autofac创建。怎么预防呢?

1 个答案:

答案 0 :(得分:0)

在应用程序的生命周期内持有DbContext并不是一件好事(mmmm,这真是一个非常糟糕的主意):

  • DbContext应该尽可能短暂。考虑到它缓存数据并跟踪更改。因此,随着时间的推移和操作在相同的背景下进行,事情会变得非常复杂
  • 使用sinlge DbContext会引发并发问题:DbContext不是线程安全的。只有它的静态方法。因此,如果您为所有MVC线程使用单个实例,您很快就会遇到各种麻烦

我希望生命周期更短,但如果使用InstancePerHttpRequest,情况会有所改善。至少,DbContext生命将更短,你将避免并发错误。