实体框架6设置连接字符串运行时

gor*_*oth 21 .net entity-framework entity-framework-6

我们处于混合环境中,我们的应用程序使用ADO.NET和Entity Framework.
由于两者都指向相同的物理SQL服务器,我们希望从配置文件中删除Entity Framework连接字符串,然后根据当前的ADO.NET连接字符串自动构建字符串.
这样可以避免开发人员更改ADO.NET字符串但忘记更改Entity Framework连接字符串的错误.

我读过这篇文章,但他们没有回答这个问题.
如何以编程方式在Entity Framework 6中为MS SQL创建连接字符串?

如果我创建自己的DbConnection并将其传递给DbContext(existingConnection,contextOwnsConnection),则会抛出错误"在Code First模式下使用上下文,其中包含从EDMX文件生成的用于Database First或Model First开发的代码. "

我没有使用Code First.

https://msdn.microsoft.com/en-us/data/jj680699
这里谈到了EF 6中的代码库配置,但文章没有显示任何实际更改连接字符串的代码.

更新:更多信息,以帮助澄清我的问题.
我不是先使用代码,而是想在配置文件之外构建一个连接字符串.
我正在使用的DbContext是T4模板生成的自动生成的DbContext文件的部分类.
我的印象是我需要创建一个继承的DbConfiguration类并在该类中执行某些操作,但我找到的唯一示例是使用Azure.
https://msdn.microsoft.com/en-us/data/jj680699
有一篇关于Code Project的文章讨论了在运行时设置连接字符串,但本文基于每次创建新实体时构建连接字符串容器.
http://www.codeproject.com/Tips/234677/Set-the-connection-string-for-Entity-Framework-at

我希望能够使用我的部分DbContext类来创建连接字符串,以便调用者不必执行任何特殊操作.

更新:RunTime的工作代码但不是DesignTime
使用由@Circular Reference"下面列出的"发布的代码,我能够更改连接字符串而不更改对我的Entity类的调用但是这对DesignTime EDMX文件不起作用.

public partial class TestEntities : DbContext
{
    public TestEntities() : base(GetSqlConnection(), true)
    {
    }

    public static DbConnection GetSqlConnection()
    {
        // Initialize the EntityConnectionStringBuilder. 
        EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder();

        var connectionSettings = ConfigurationManager.ConnectionStrings("Current_ADO_Connection_In_Config");

        // Set the provider name. 
        entityBuilder.Provider = connectionSettings.ProviderName;

        // Set the provider-specific connection string. 
        entityBuilder.ProviderConnectionString = connectionSettings.ConnectionString;

        // Set the Metadata location. 
        entityBuilder.Metadata = "res://*/Models.TestModel.csdl|res://*/Models.TestModel.ssdl|res://*/Models.TestModel.msl";

        return new EntityConnection(entityBuilder.ToString());
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我能让DesignTime正常工作,那就更好了.

jac*_*ric 22

您可以使用配置文件中的连接字符串在设计时工作.

<add name="DWContext" connectionString="metadata=res://*/Database.DWH.DWModel.csdl|res://*/Database.DWH.DWModel.ssdl|res://*/Database.DWH.DWModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=SQLSERVER_INSTANCE;initial catalog=DB_NAME;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
Run Code Online (Sandbox Code Playgroud)

所以不要删除它,因为你只需要在设计时使用它.

使用此方法在运行时以动态方式工作(类似于上一个方法):

扩展数据上下文分部类:

public partial class DWContext
{
    public DWContext(string nameOrConnectionString)
        : base(nameOrConnectionString)
    {
    }

    /// <summary>
    /// Create a new EF6 dynamic data context using the specified provider connection string.
    /// </summary>
    /// <param name="providerConnectionString">Provider connection string to use. Usually a standart ADO.NET connection string.</param>
    /// <returns></returns>
    public static DWContext Create(string providerConnectionString)
    {
        var entityBuilder = new EntityConnectionStringBuilder();

        // use your ADO.NET connection string
        entityBuilder.ProviderConnectionString = providerConnectionString;

        entityBuilder.Provider = "System.Data.SqlClient";

        // Set the Metadata location.
        entityBuilder.Metadata = @"res://*/Database.DWH.DWModel.csdl|res://*/Database.DWH.DWModel.ssdl|res://*/Database.DWH.DWModel.msl";

        return new DWContext(entityBuilder.ConnectionString);
    }

}
Run Code Online (Sandbox Code Playgroud)

并从您的代码创建一个新的EF数据上下文:

private DWContext db = DWContext.Create(providerConnectionString);
Run Code Online (Sandbox Code Playgroud)

再见 ;-)


Nic*_*ris 14

您将获得Code First模式异常,因为您正在DbConnection使用ADO.NET连接字符串传递构建.此连接字符串不包含对元数据文件的引用,因此EntityFramework不知道在何处找到它们.

DbContext使用适当的以编程方式设置连接字符串来创建,请使用EntityConnectionStringBuilder类.

var entityBuilder = new EntityConnectionStringBuilder();

// use your ADO.NET connection string
entityBuilder.ProviderConnectionString = conString;

// Set the Metadata location.
entityBuilder.Metadata = @"res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl";
var dbContext = new DbContext(entityBuilder.ConnectionString);
Run Code Online (Sandbox Code Playgroud)