默认连接工厂是否影响使用 EF Code First 生成的密钥和索引



最初,我们的解决方案将 System.Data.Entity.Infrastructure.LocalDbConnectionFactory 设置为我们的 web.config 中的默认连接工厂类型。

<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
  <parameters>
    <parameter value="v11.0" />
  </parameters>

我不确定我们是否真的需要这样的它,因为我们使用本地SQL Server进行开发,使用SQL Azure进行实际部署。 我们使用 EF Code First,并使用名为 PK_dbo 的键创建表。客户和FK_dbo。Customers_dbo。Employers_EmployerID,并为每个外键(如 IX_EmployerID)创建一个索引。

我们已经切换到基于本文中的想法的自定义连接工厂,用于Robert Moore创建的ReliableDbProvider,因为我们希望为SQL Azure的暂时性故障内置重试逻辑。 它似乎工作正常,但似乎也会导致键以不同的方式命名(PK__Customer__A4AE64B8BB3388DF、Customer_Employer)并且无法生成索引。

没想到工厂会影响这一代人。 知道它有什么贡献吗?

在反映一些代码之后,似乎它与DropCreateDatabaseIfModelChanges初始化设定项中使用的DbMigrationsConfiguration类的工作方式有关,因此我们必须看看是否可以以某种方式覆盖它。

public DbMigrationsConfiguration()
{
this.SetSqlGenerator("System.Data.SqlClient", new SqlServerMigrationSqlGenerator());
this.SetSqlGenerator("System.Data.SqlServerCe.4.0", new SqlCeMigrationSqlGenerator());
this.CodeGenerator = new CSharpMigrationCodeGenerator();
}

仍然对想法持开放态度!

根据一些反射的代码,看起来问题在于 DatabaseCreator 类中的非 System.Data.SqlClient 或 sqlce 提供程序存在硬编码逻辑,这会迫使生成走不同的路径。

public void CreateDatabase(InternalContext internalContext, Func<DbMigrationsConfiguration, DbContext, DbMigrator> createMigrator, ObjectContext objectContext)
    {
        if (internalContext.CodeFirstModel == null || !(internalContext.ProviderName == "System.Data.SqlClient") && !(internalContext.ProviderName == "System.Data.SqlServerCe.4.0"))
        {
            internalContext.DatabaseOperations.Create(objectContext);
            internalContext.SaveMetadataToDatabase();
        }
        else
        {
            Type type = internalContext.Owner.GetType();
            DbMigrationsConfiguration dbMigrationsConfiguration = new DbMigrationsConfiguration();
            dbMigrationsConfiguration.ContextType = type;
            dbMigrationsConfiguration.AutomaticMigrationsEnabled = true;
            dbMigrationsConfiguration.MigrationsAssembly = type.Assembly;
            dbMigrationsConfiguration.MigrationsNamespace = type.Namespace;
            dbMigrationsConfiguration.TargetDatabase = new DbConnectionInfo(internalContext.OriginalConnectionString, internalContext.ProviderName);
            createMigrator(dbMigrationsConfiguration, internalContext.Owner).Update();
        }
        internalContext.MarkDatabaseInitialized();
    }

最后,我们更新了数据上下文构造函数,以便 DefaultConnectionFactory 是在代码中设置的,而不是在配置中设置的。 仅在开发(调试模式)中,如果 db 不存在,我们首先设置 SqlConnectionFactory,因为它生成具有我们想要的索引和更好命名的数据库。 之后或处于发布模式,我们希望使用具有我们想要的重试逻辑的自定义提供程序。

最新更新