在app.config中配置自定义数据库初始化程序

时间:2015-02-25 09:17:18

标签: entity-framework

我们有一个自定义初始化程序,它不会以任何方式更改数据库模式;它所做的就是播种一些数据。 我被要求提出一个自定义初始化程序,它将始终删除数据库,然后使用相同的种子数据填充它(这将仅在我们的数据库测试项目中使用)。

我写过这个初始化程序:

public class DropAndSeedDbInitializer<TContext, TSeedDataInitializer> : IDatabaseInitializer<TContext>
        where TContext : DbContext
        where TSeedDataInitializer : IDatabaseInitializer<TContext>, new()
    {
        private readonly DropCreateDatabaseAlways<TContext> _dbInitializer;
        private readonly IDatabaseInitializer<TContext> _seedDataInitializer;

        public DropAndSeedDbInitializer()
        {
            _dbInitializer = new DropCreateDatabaseAlways<TContext>();
            _seedDataInitializer = Activator.CreateInstance<TSeedDataInitializer>();
        }

        public void InitializeDatabase(TContext context)
        {
            context.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction
                , string.Format("ALTER DATABASE [{0}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE", context.Database.Connection.Database));

            _dbInitializer.InitializeDatabase(context);
            _seedDataInitializer.InitializeDatabase(context);
        }
    }

我打电话时工作正常

LicenceContext context = new LicenceContext();
Database.SetInitializer(new DropAndSeedDbInitializer<LicenceContext, TestSeedDataInitializer>());
context.Database.Initialize(true);

然后我决定在app.config中配置它,如下所示:

<context type="Foo.LicenceContext, MyAssembly">
  <databaseInitializer
    type="Foo.DropAndSeedDbInitializer`2[[Foo.LicenceContext, MyAssembly], Foo.TestSeedDataInitializer, MyAssembly]], MyAssembly" />
</context>

我删除了这段代码:

Database.SetInitializer(new DropAndSeedDbInitializer<LicenceContext, TestSeedDataInitializer>());
context.Database.Initialize(true);

但是当我第一次尝试访问我的上下文时,我得到了这个错误:

Failed to set database initializer of type 'Foo.DropAndSeedDbInitializer`2[[Foo.LicenceContext, MyAssembly], Foo.TestSeedDataInitializer, MyAssembly]], MyAssembly' for DbContext type 'Foo.LicenceContext, MyAssembly' specified in the application configuration. See inner exception for details.

内部例外是:

Exception of type 'System.ArgumentException' was thrown.
Parameter name: typeName@149

at System.Data.Entity.Internal.InitializerConfig.TryGetInitializer(Type requiredContextType, String contextTypeName, String initializerTypeName, Boolean isDisabled, Func`1 initializerArgs, Func`3 exceptionMessage)
at System.Data.Entity.Internal.InitializerConfig.<>c__DisplayClass6.<TryGetInitializerFromEntityFrameworkSection>b__1(ContextElement e)
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
at System.Data.Entity.Internal.InitializerConfig.TryGetInitializerFromEntityFrameworkSection(Type contextType)
at System.Data.Entity.Internal.InitializerConfig.TryGetInitializer(Type contextType)
at System.Data.Entity.Infrastructure.DependencyResolution.AppConfigDependencyResolver.GetServiceFactory(Type type, String name)
at System.Data.Entity.Infrastructure.DependencyResolution.AppConfigDependencyResolver.<>c__DisplayClass1.<GetService>b__0(Tuple`2 t)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at System.Data.Entity.Infrastructure.DependencyResolution.AppConfigDependencyResolver.GetService(Type type, Object key)
at System.Data.Entity.Infrastructure.DependencyResolution.ResolverChain.<>c__DisplayClass3.<GetService>b__0(IDbDependencyResolver r)
at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()

然后我创建了一个继承自DropAndSeedDbInitializer的类,如下所示:

public class DummyInitializer : DropAndSeedDbInitializer<LicenceContext, TestSeedDataInitializer>
{
}

我在app.config中配置了它,如下所示:

<context type="Foo.LicenceContext, MyAssembly">
  <databaseInitializer
    type="Foo.DummyInitializer, MyAssembly" />
</context>

然后DropAndSeedDbInitalizer运行,我可以毫无问题地访问我的上下文。

所以我的问题是:我应该能够在app.config中配置这个自定义初始化程序吗?如果我应该,我做错了什么?

谢谢,

大卫

0 个答案:

没有答案