您将在下面找到我的自定义IDbContextFactory实现。在我的存储库中,我创建了这个工厂的实例,因为我正在做一个多租户应用程序(每个租户都有自己的数据库)我还需要设置ConnectionString和Tenant属性,以便可以创建我的DbContext。
如果数据库不存在,这一切都很有用,但是当我需要执行迁移时,DbMigrationsConfiguration会尝试使用此工厂来创建EFDbContext的实例,当然它会因为未设置ConnectionString和Tenant而失败。
是否有人有解决此问题的替代策略?
public class DbContextFactory : IDbContextFactory<EFDbContext>
{
public string ConnectionString { get; set; }
public string Tenant { get; set; }
public EFDbContext Create()
{
var connectionInfo = new DbConnectionInfo(ConnectionString, "System.Data.SqlClient");
if (EFContextHelper.Contexts.Contains(Tenant))
{
return new EFDbContext(ConnectionString, Tenant);
}
else
{
EFDbContext context = new EFDbContext(ConnectionString, Tenant);
if (!context.Database.Exists())
{
Database.SetInitializer<EFDbContext>(new EFDbContextInitializer());
context.Database.Initialize(false);
}
else
{
bool doMigration = false;
try
{
doMigration = !context.Database.CompatibleWithModel(true);
}
catch (NotSupportedException)
{
// no metadata for migration
doMigration = true;
}
// not working cause migrator is trying to instantiate this factory without setting connection string etc
if (doMigration)
{
var migrationConfig = new DbMigrationsConfiguration<EFDbContext>();
migrationConfig.AutomaticMigrationDataLossAllowed = false;
migrationConfig.AutomaticMigrationsEnabled = true;
migrationConfig.TargetDatabase = connectionInfo;
var migrator = new DbMigrator(migrationConfig);
migrator.Update();
}
}
EFContextHelper.Contexts.Add(Tenant);
return context as EFDbContext;
}
}
谢谢, 加里
答案 0 :(得分:2)
我设法自己解决了这个问题。由于我没有收到任何回复,所以我会把这个问题留给其他遇到此问题的人。
基本上我只是将我的DbContext类实例化调整为以下内容:
public EFDbContext(string connectionString, string tenant) : base(connectionString ?? "EFDBContext")
{
Tenant = tenant;
}
因此,在这种情况下,如果传递的连接字符串为空,则默认为配置文件连接字符串名称。迁移器似乎保持在以下位置分配连接:
migrationConfig.TargetDatabase = connectionInfo;
希望这有助于某人。