使用自定义ConnectionString和DbProviderInfo创建DbContext

时间:2012-09-05 14:57:38

标签: sql-server entity-framework ef-code-first connection-string dbcontext

我们有许多共享相同架构的数据库。它们分布在许多SQL Server上,有些是2005年,有些是2008年。我们在连接到2008服务器之后连接到2008服务器时遇到异常,首先说明如下:

  

更新条目时发生错误。查看内部异常   详情。       更新条目时发生错误。有关详细信息,请参阅内部异常       正在使用的SQL Server版本不支持数据类型“datetime2”。

据我所知,正在发生的是根据2008 SQL服务器提供程序信息创建模型,因此当连接到2005服务器时,它不能使用DateTime2数据类型,因为那里不支持

我们想针对2005服务器构建模型,但我不确定如何指定连接字符串和DbCompiledModel。以前我有几个构造函数接受连接字符串(以及其他参数)......

    public ProjectContext(string ConnectionString) : base(ConnectionString)
    {

        // Get the ObjectContext related to this DbContext
        var objectContext = (this as IObjectContextAdapter).ObjectContext;

        // ... does some stuff with the ObjectContext
    }

如何针对ALL上下文(最小公分母)指定针对2005服务器构建的已编译模型,还指定连接字符串?我现在还没有办法做到这一点。

任何帮助都将不胜感激。

编辑: 我们正在使用Entity Framework 4.3 Code First,因此,没有设计时EDMX文件可供编辑。

2 个答案:

答案 0 :(得分:2)

基类构造函数有一个重载!

我将OnModelCreating配置内容复制到一个返回名为BuildModel的DbCompiledModel的新方法中。当我调用具有ConnectionString构造函数的构造函数时,我得到dbModel的值,这是一个私有的readonly属性,如果为null,则设置为从BuildModel返回的值。属性值与连接字符串一起被提供给基类​​构造函数。

我可以访问我要连接的SQL Server版本。最终,我将把它带入并创建一个2005年的模型和一个2008年的模型。

我会暂时保持这种状态,以防万一有更好的方法可以做到这一点。

public DbContext ProjectContext (string ConnectionString) 
    : base(ConnectionString, dbModel)
{

}

private DbCompiledModel _dbModel;
private DbCompiledModel dbModel;
{
    get
    {
        if (_dbModel == null)
        {
            _dbModel = BuildModel(new DbModelBuilder());
        }
        return _dbModel;
    }
}

    private DbCompiledModel BuildModel(DbModelBuilder builder)
    {
        //Some configuration stuff
        return builder.Build(new DbProviderInfo("System.Data.SqlClient", "2005"))
                      .Compile();
    }

答案 1 :(得分:1)

要回答第一个问题,您需要直接编辑edmx xml文件,然后更改  2008年至2005年的ProviderManifestToken属性,位于文件顶部的<Schema>元素。

AFAIK您需要为每个.edmx文件执行此操作,更糟糕的是,每次从数据库更新模型时,模型更新向导都将恢复ProviderManifestToken,具体取决于EF连接使用的SQL版本。 AFAIK EF向导使用包含edmx的本地程序集中的连接字符串,因此如果您将该连接字符串更改为指向SQL 2005 DB,那么您应该可以继续。