动态连接字符串的设置entity framework

我正在开发一个应用程序,它将在多个数据库中使用相同的数据库模式。 出于这个原因,我创建了一个名为MyTemplate的数据库。 创建新用户时,他们将拥有自己的数据库实例。 因此,将创建一个名为MyTemplate_[UserName]的数据库。 当用户登录时,我需要将他们的查询指向他们的数据库。 出于这个原因,我知道我需要在运行时设置连接字符串。 我的问题是,我也想使用entity framework。

目前,我使用MyTemplate作为源创建了一个新的.edmx。 我以为我能够更新代码并在那里设置连接字符串。 不幸的是,我无法弄清楚如何设置它。 TemplateEntities的构造函数没有允许我传入连接字符串的重载。 我注意到TemplateEntities派生自DbContext,我不认为这会是问题所在。

 string connectionString = GetUsersConnectionString(); using (TemplateEntities entities = new TemplateEntities()) { TemplateEntity entity = new TemplateEntity(); // Save to the database entities.TemplateEntity.Add(entity); entities.SaveChanges(); } 

我是否错误地创建了.edmx ? 或者我完全错过了什么? 我谷歌的所有内容都显示了一个应该允许传入连接字符串的重载。但是,我没有可用的重载。

生成的TemplateEntities类标记为partial

您所要做的就是使用部分类定义的另一部分添加另一个文件,该部分公开了您要使用的构造函数:

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

然后将您的连接字符串传递给此构造函数。

您希望将此代码放在不同的文件中,以便在更新edmx模型时不会覆盖该代码。

尼古拉斯巴特勒的回答非常正确。 除了他所说的,我还面临着为entity framework获取现有连接字符串并将其指向具有相同结构的不同数据库的问题。 我使用以下代码仅更改现有字符串的数据源:

 var originalConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["CSName"].ConnectionString; var ecsBuilder = new EntityConnectionStringBuilder(originalConnectionString); var sqlCsBuilder = new SqlConnectionStringBuilder(ecsBuilder.ProviderConnectionString) { DataSource = "newDBHost" }; var providerConnectionString = sqlCsBuilder.ToString(); ecsBuilder.ProviderConnectionString = providerConnectionString; string contextConnectionString = ecsBuilder.ToString(); using (var db = new SMSContext(contextConnectionString)) { ... } 

这是我在构建解决方案时使用的一步一步:

  1. 在您想要的项目上,确保使用“Manage Nuget Packages …”选项菜单安装Entity Framework。
  2. 在所需项目上,右键单击,然后单击添加 – >新项,转到数据并选择ADO.NET实体数据模型。
  3. 输入模型的名称,让我们说“ExampleModel”。 单击添加。
  4. 将出现四种选择来选择模型内容,我通常选择第一种,以便从数据库中的现有对象构建模型。 点击下一步。
  5. 设置数据连接。 完成后,键入模型实体的名称,例如“ExampleModelEntities”,单击“下一步”。
  6. 从数据库中选择将出现在EF模型上的对象。 在“模型名称空间”输入框中,键入步骤3中的相同模型名称(“ExampleModel”)。 单击完成。

此时,已创建一个新的.edmx文件并将其添加到项目中,其中包含所有准备工作的对象。 到目前为止,只有非期望的细节已经指定了连接字符串并保存到我们项目的Web.config文件中。

要删除它,只需转到Web.config的部分块,然后从中删除详细信息。 我们现在将致力于使连接字符串从其他源动态可读。

正如Nicholas Butler所指出的,接下来的事情将是创建原始部分实体类(ExampleModelEntities)的“版本”,这将允许我们传递动态连接字符串。 这是可能的,因为创建的原始实体类inheritance自DBContext,DBContext是包含传递此类连接的构造函数的DBContext。

要执行上述操作,请在项目中添加一个新的空类。 确保在我们的案例研究“ExampleModelEntities”之后键入步骤5中提供的相同名称。 下面的代码实现:

C#

 public partial class ExampleModelEntities { public ExampleModelEntities(string connString) : base(connString) { } } 

VB.Net:

 Partial Public Class ExampleModelEntities Public Sub New(ByVal connString As String) MyBase.New(connString) End Sub End Class 

此时,您的代码已准备好使用来自其他源的动态连接字符串。 其中一个源可能是传递来自另一个存储在不同数据库中的字段或使用EntityConnectionStringBuilder类的连接字符串。

以下示例在VB.Net中实现,但请使用Telerik之类的工具进行翻译。 假设我们从某个数据库中获取对象列表,只是我们想要动态传递来自存储在不同数据库中的另一个字段的连接字符串。 为此,代码如下所示:

 Public Shared Function Get_List(ByVal Param1 As String) As List(Of Stored_Procedure_Code_Result) Try Dim Object_List_Result As List(Of Stored_Procedure_Code_Result) = Nothing Using dbContext As New ExampleModelEntities(Configuration.CONNECTION_STRING) Object_List_Result = dbContext.Stored_Procedure_Code(Param1).ToList dbContext.Dispose() End Using Return Object_List_Result Catch ex As Exception Throw ex End Try End Function 

其中Configuration.CONNECTION_STRING是动态连接字符串的值,使用名为“Configuration”的模块和检索此类值的函数表示。

为避免格式不准确,应使用以下格式存储该值:

对于使用Entity Framework的Windows身份validation:

 UPDATE [DBConnections].[dbo].[ListOfConnectionsTable] SET ConnValue = 'metadata=res://*/ExampleModel.csdl|res://*/ExampleModel.ssdl|res://*/ExampleModel.msl;provider=System.Data.SqlClient;provider connection string="Data Source=ServerName;Initial Catalog=DBName;Integrated Security=True"' 

对于使用Entity Framework的SQL身份validation:

 UPDATE [DBConnections].[dbo].[ListOfConnectionsTable] SET ConnValue = 'metadata=res://*/ExampleModel.csdl|res://*/ExampleModel.ssdl|res://*/ExampleModel.msl;provider=System.Data.SqlClient;provider connection string="Persist Security Info=False;User ID=XXXXXX;Password=XXXXXXX;Initial Catalog=DBName;Data Source=ServerName;App=YourAppName;Network Library=dbmssocn"' 

最后,扩展Mark提供的答案,在Microsoft,有一个关于如何使用EntityConnectionStringBuilder类的详细解释,该类也可用于构建动态连接字符串,然后根据需要传递此值。