.net Entity Framework 6 设置连接字符串运行时

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29440405/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 09:38:38  来源:igfitidea点击:

Entity Framework 6 set connection string runtime

.netentity-frameworkentity-framework-6

提问by goroth

We are in a mixed environment where our application is using both ADO.NET and Entity Framework.
Since both are pointing to the same physical SQL server, we would like to remove the Entity Framework connection string from the config file and then auto build the string based on the current ADO.NET connection strings.
This saves us from mistakes where a developer changed the ADO.NET string but forgot to change the Entity Framework connection string.

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

I have read this but they did not answer the question.
How do I create connection string programmatically to MS SQL in Entity Framework 6?

我读过这个,但他们没有回答这个问题。
如何在实体框架 6 中以编程方式创建到 MS SQL 的连接字符串?

If I create my own DbConnection and pass that to the DbContext(existingConnection, contextOwnsConnection) then it throws an error "The context is being used in Code First mode with code that was generated from an EDMX file for either Database First or Model First development."

如果我创建自己的 DbConnection 并将其传递给 DbContext(existingConnection, contextOwnsConnection) 然后它会抛出错误“上下文正在代码优先模式下使用,代码是从数据库优先或模型优先开发的 EDMX 文件生成的。 ”

I am not using Code First.

我没有使用代码优先。

https://msdn.microsoft.com/en-us/data/jj680699
This talked about code base configuration in EF 6 but the article does not show any code that actually changed the connection string.

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

UPDATED: More information to help clarify my question.
I am NOT using code first and would like to build a connection string outside of the config file.
The DbContext I am using is a partial class to the auto generated DbContext file that the T4 template is generating.
I was under the impression that I needed to create an inherited DbConfiguration class and do something in that class but the only example I find is using Azure.
https://msdn.microsoft.com/en-us/data/jj680699
There is an article on Code Project that talks about setting the connection string at runtime but the article is based on building a connection string every time I create a new Entity container.
http://www.codeproject.com/Tips/234677/Set-the-connection-string-for-Entity-Framework-at

更新:更多信息有助于澄清我的问题。
我不是先使用代码,而是想在配置文件之外构建一个连接字符串。
我使用的 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

I would like to be able to use my partial DbContext class to create the connection string so that the caller does not have to do anything special.

我希望能够使用我的部分 DbContext 类来创建连接字符串,以便调用者不必做任何特殊的事情。

UPDATED: Working code for RunTime but not DesignTime
Using code posted by @Circular Reference "listed below", I was able to change the connection string without changing the calls to my Entity class BUT this does not work for DesignTime EDMX file.

更新:RunTime 的工作代码而不是 DesignTime
使用@Circular Reference 发布的代码“下面列出”,我能够更改连接字符串而不更改对我的实体类的调用,但这不适用于 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());
    }
}

Now if I can just get the DesignTime working then that would be good.

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

采纳答案by Nick Patsaris

You are getting the Code First mode exception because you are passing a DbConnectionbuilt with the ADO.NET connection string. This connection string does not include references to metadata files, so EntityFramework does not know where to find them.

您收到 Code First 模式异常,因为您传递的DbConnection是使用 ADO.NET 连接字符串构建的。此连接字符串不包括对元数据文件的引用,因此 EntityFramework 不知道在哪里可以找到它们。

To create a DbContextwith an appropriate programmatically set connection string, use the EntityConnectionStringBuilderclass.

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);

回答by Hymantric

You can work at design time using the connection string in your config file.

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

<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" />

So don't remove it because you need it ONLY at design time.

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

Work instead in a dynamic way at runtime using this approach (similar to your last one):

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

Extend the data context partial class:

扩展数据上下文部分类:

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);
    }

}

And from your code create a new EF data context with:

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

private DWContext db = DWContext.Create(providerConnectionString);

Ciao ;-)

再见 ;-)