Entity Framework运行时连接字符串

12

我想在运行时提供数据库的连接字符串,我正在使用Entity Framework。以下是我目前的代码:

class MyClassDBContext:DbContext
{
  public MyClassDBContext(string str) : base(str)
  {
    this.Database.Connection.ConnectionString = str;
  }
}

为了使用上述代码,我尝试了

//create connection string
EntityConnectionStringBuilder myConn = new EntityConnectionStringBuilder();
myConn.Provider = "System.Data.SqlClient";
myConn.ProviderConnectionString = "user id=xxxx;password=xxxx;server=localhost;database=xxxx;connection timeout=30";

//inject the connection string at runtime
MyClassDBContext a = new MyClassDBContext(myConn.ToString())

以上代码给我返回了一个错误,说“提供程序关键字不受支持”。为了尝试调试此错误,我尝试了以下操作:

 MyClassDBContext a = new MyClassDBContext("metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;provider=System.Data.SqlClient;provider connection string=user id=xxxx;password=xxxx;server=localhost;database=xxxx;connection timeout=30")

现在,我收到了一个错误,说“不支持元数据关键字”。所以我修改了我的代码为:

MyClassDBContext a = new MyClassDBContext("provider=System.Data.SqlClient;provider connection string=user id=xxxx;password=xxxx;server=localhost;database=xxxx;connection timeout=30")

现在我收到一个错误,说“不支持提供程序关键字”。所以我再次更改了我的代码:

 MyClassDBContext a = new MyClassDBContext("user id=xxxx;password=xxxx;server=localhost;database=xxxx;connection timeout=30")

现在它运行良好!我的问题是:如何在运行时指定提供程序和元数据?似乎只接受连接字符串。我正在使用来自Nuget的Entity 4.3.1。

谢谢

5个回答

13

基于edmx文件的EF需要提供"Provider"和"Metadata"内容。而基于代码优先的EF不需要这些,只需普通的连接字符串即可。如果你喜欢,可以使用SqlConnectionStringBuilder(而不是EntityConnectionStringBuilder)来构建这个常规连接字符串。但正如你所看到的,你只需要指定实际的连接细节即可,不需要在EF 4.3.1的DbContext代码优先范式中使用Provider和Metadata。


1
如果我需要使用代码优先连接到Oracle或MySQL,我该怎么做呢? - user1625066
4
EF连接字符串包含 Provider="System.Data.Entity"ConnectionString="res://big.csdl|res://ball.ssdl|res://mud.msl; provider connection string="..."。普通的连接字符串包含 Provider="System.Data.Client"(或Oracle或MySql)和 ConnectionString="details to connect to it"。这两个参数通常在app.config或web.config中,但您选择动态构造它们。在EF Code First中,您采用第二种方法。在EDMX领域中,您必须将第二条路径的详细信息嵌入到第一条路径的“Provider Connection String”中。这很丑陋。 - robrich
1
它与 SqlConnectionStringBuilder 兼容(而不是 SqlConnectionBuilder)。 - Malick

10

HatSoft的回答基础上构建:

var entityConnectionStringBuilder= new EntityConnectionStringBuilder();
entityConnectionStringBuilder.Provider = "System.Data.SqlClient";
entityConnectionStringBuilder.ProviderConnectionString = <your SQL Server connection string>;
entityConnectionStringBuilder.Metadata = "res://*";

MyClassDBContext a = new MyClassDBContext(entityConnectionStringBuilder.ToString());

@BKSpurgeon 我还没有使用过那个数据库,用完后告诉我们你的发现吧 :-) - David McClelland
是的,有一个字符串构建器类 - 但我发现它有点不稳定,对于新手来说有点困难 - 最终我选择了使用MySQL。 - BenKoshy

7

EntityConnectionStringBuilder类可用于在运行时指定提供程序和元数据。

例如:

var entityConnectionStringBuilder = new EntityConnectionStringBuilder(); entityConnectionStringBuilder.Provider = "System.Data.SqlClient"; entityConnectionStringBuilder.Metadata = "res:///Example.csdl|res:///Example.ssdl|res://*/Example.msl";

有关元数据中CSDL、SSDL和MSDL的更多信息,请参见此处


是的,这就是我尝试过的,但它没有起作用。代码给了我“提供程序关键字不受支持或元数据关键字不受支持”的错误。请参见原帖获取详细信息。 - user1625066
提供程序 = "System.Data.SqlClient",这不应该是提供程序 = "System.Data.EntityClient" 吗? - HatSoft
可能是真的,但是当前更改提供程序并没有帮助,因为我仍然收到相同的错误提示,即不支持“provider”关键字。 - user1625066

4
我跟随了这个链接 还有这个
如何在没有app.conf文件的情况下使用EF Code-First?
基本上我做的和你差不多,创建一个带有字符串参数的构造函数并调用基类。
但我也在这个构造函数中设置了提供程序。
这里是一个例子
public Context(string ConnectionString) : base(ConnectionString) { 
    Database.DefaultConnectionFactory = new SqlCeConnectionFactory("Oracle.DataAccess.Client"); 
}

那样你可以指定提供程序。并且你不需要在连接字符串中指定,因此不会出现提供程序关键字错误。
这是我调用它的方式。
var dbCont = new ClassLibrary1.Models.Context("DATA SOURCE=xxx;PASSWORD=xxx;USER ID=xxx");

希望这有所帮助,我花了很长时间才找到它。

2

这是一个老问题,但对某些人可能仍有用处

 var provider = (DbProviderFactory)System.Data.Entity.DbConfiguration
            .DependencyResolver
            .GetService(typeof(DbProviderFactory), "invariant provider name");

        var conn = provider.CreateConnection();
        //conn.ConnectionString = "sample connection string";

        DbInterception.Dispatch.Connection.SetConnectionString(conn, new DbConnectionPropertyInterceptionContext<string>()
            .WithValue("sample connection string"));

return new SampleDbContext(conn,true);

谢谢你的回答!我遇到的问题是我的代码中没有使用CSDL、SSDL或MSDL,因此我没有什么可以设置Metadata属性的东西(也无法输入"res://*")。通过按照您的建议,我能够克服这个限制。非常感谢! - DigiOz Multimedia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接