c# - 如何将连接字符串注入(inject) IDbContextFactory<T> 的实例?

标签 c# entity-framework asp.net-mvc-4 dependency-injection unity-container

我将 Entity Framework 5 与 Code First 迁移结合使用。我有一个 DataStore派生自 DbContext 的类:

public class DataStore : DbContext, IDataStore
{
    public int UserID { get; private set; }

    public DataStore(int userId, string connectionString) : base(connectionString)
    {
        UserID = userId;
    }

    public virtual IDbSet<User> Users { get; set; }

    // Rest of code here
}

还有一个创建 DataStore 实例的工厂类类:

public class DataStoreFactory : Disposable, IDataStoreFactory
{
    private DataStore _database;
    private int _userId;
    private string _connectionString;

    public DataStoreFactory(int userId, string connectionString)
    {
        _userId = userId;
        _connectionString = connectionString;
    }

    public IDataStore Get()
    {
        _database = new DataStore(_userId, _connectionString);
        return _database;
    }

    protected override void DisposeCore()
    {
        if (_database != null) _database.Dispose();
    }
}

这些类的构造函数参数在运行时注入(inject) Unity .到目前为止一切顺利,一切都很好!

问题出现在我们进行迁移时:因为我的 DataStore context 类没有默认构造函数,我需要提供 IDbContextFactory<T> 的实现以便 Code First Migrations 可以实例化它:

public class MigrationDataStoreFactory : IDbContextFactory<DataStore>
{
    public DataStore Create()
    {
        // Need to inject connection string so we can pass it to this constructor
        return new DataStore(0, "CONNECTION_STRING_NEEDED_HERE"); 
    }
}

问题是我不知道如何将连接字符串注入(inject)此类。我无法使用这样的连接字符串参数创建新的构造函数:

public class MigrationDataStoreFactory : IDbContextFactory<DataStore>
{
    public string _connectionString { get; set; }

    public MigrationDataStoreFactory(string connectionString)
    {
        _connectionString = connectionString;
    }

    public DataStore Create()
    {
        return new DataStore(0, new DateTimeProvider(() => DateTime.Now), _connectionString);
    }
}

如果这样做,我会在运行时收到迁移抛出的以下异常:

[InvalidOperationException: The context factory type 'MigrationDataStoreFactory' must have a public default constructor.]
    System.Data.Entity.Infrastructure.DbContextInfo.CreateActivator() +326
    System.Data.Entity.Infrastructure.DbContextInfo..ctor(Type contextType, DbProviderInfo modelProviderInfo, AppConfig config,     DbConnectionInfo connectionInfo) +106
    System.Data.Entity.Infrastructure.DbContextInfo..ctor(Type contextType) +52
    System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration, DbContext usersContext) +202
    System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration) +66
    System.Data.Entity.MigrateDatabaseToLatestVersion`2.InitializeDatabase(TContext context) +50
    // Truncated stack trace, but you get the idea

除此之外,这个类无论如何都不会被 Unity 实例化; Code First Migrations 似乎只是按照惯例以某种方式调用它,所以即使我能做到,也无济于事......

如果我在该方法中对连接字符串进行硬编码,则一切正常,但出于显而易见的原因,我不想这样做。

有人可以帮忙吗?

最佳答案

对于那些可以升级到 Entity Framework 6 的人来说,有一个新的迁移初始化重载使这更容易:

    // Parameters:
    //   useSuppliedContext:
    //     If set to true the initializer is run using the connection information from the
    //     context that triggered initialization. Otherwise, the connection information
    //     will be taken from a context constructed using the default constructor or registered
    //     factory if applicable.
    public MigrateDatabaseToLatestVersion(bool useSuppliedContext);

使用它,您可以使用注入(inject)的 DbContext 运行迁移,如下所示:

Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDbContext, MyMigrationConfiguration>(useSuppliedContext: true));

using (var context = kernel.Get<MyDbContext>())
    context.Database.Initialize(false);

关于c# - 如何将连接字符串注入(inject) IDbContextFactory<T> 的实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18734496/

相关文章:

c# - 使用正则表达式修剪 html

c# - 从服务器 asp.net 下载文件

c# - C#中如何通过引用传递值?

entity-framework - EF 代码优先 - 无法检查模型兼容性,因为数据库不包含模型元数据

c# - LINQ Union 不同类型 - 动态转换为接口(interface)?

c# - 将 sql 查询重写为 LINQ。找不到错误

database - ADO.Net EF - 如何在模型优先方法中定义外键关系?

c# - 如何启用迁移以在 MVC4 中更新我的数据库?

asp.net-mvc-4 - Mvc4 模型到 url 查询字符串

c# - MVC C# 奇怪的 NullReferenceException