簡體   English   中英

為動態連接字符串設置實體框架

[英]Setup Entity Framework For Dynamic Connection String

我正在開發一個應用程序,它將跨多個數據庫使用相同的數據庫架構。 為此,我創建了一個名為MyTemplate的數據庫。 創建新用戶時,他們將擁有自己的數據庫實例。 因此,將創建一個名為MyTemplate_[UserName]類的數據庫。 當用戶登錄時,我需要將他們的查詢指向他們的數據庫。 出於這個原因,我知道我需要在運行時設置連接字符串。 我的問題是,我也想使用實體框架。

目前,我使用 MyTemplate 作為源創建了一個新的 .edmx。 我以為我可以更新代碼並在那里設置連接字符串。 不幸的是,我不知道如何設置它。 TemplateEntities 的構造函數沒有允許我傳入連接字符串的重載。 我注意到從 DbContext 派生的 TemplateEntities,我認為這不是問題。

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 模型時不會被覆蓋。

尼古拉斯巴特勒的回答是非常正確的。 除了他所說的之外,我還面臨着為實體框架獲取現有連接字符串並將其指向具有相同結構的不同數據庫的問題。 我使用以下代碼僅更改現有字符串的數據源:

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. 在您想要的項目上,確保使用“管理 Nuget 包...”選項菜單安裝了實體框架。
  2. 在您想要的項目上,右鍵單擊,然后添加->新建項目,轉到數據並選擇 ADO.NET 實體數據模型。
  3. 輸入模型的名稱,比如說“ExampleModel”。 單擊添加。
  4. 選擇模型內容會出現四個選項,我通常選擇第一個,以便從數據庫中的現有對象構建模型。 點擊下一步。
  5. 設置數據連接。 完成后,輸入模型實體的名稱,比如說“ExampleModelEntities”,單擊“下一步”。
  6. 從數據庫中選擇將出現在 EF 模型上的對象。 在模型命名空間輸入框中輸入與步驟 3 相同的模型名稱(“ExampleModel”)。 單擊完成。

此時,一個新的 .edmx 文件已創建並添加到項目中,其中包含所有准備工作的對象。 只有不想要的細節是,到目前為止連接字符串已被指定並保存到我們項目的 Web.config 文件中。

要刪除它,只需轉到 Web.config 的<connectionStrings></connectionStrings>部分塊並從那里刪除詳細信息。 我們現在將致力於使連接字符串可從其他來源動態讀取。

正如 Nicholas Butler 所指出的,接下來要做的是創建原始部分實體類(ExampleModelEntities)的“版本”,這將允許我們傳遞動態連接字符串。 這是可能的,因為創建的原始實體類繼承自 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”的模塊和檢索此類值的函數表示。

為避免格式不准確,應使用以下格式存儲該值:

對於使用實體框架的 Windows 身份驗證:

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

對於使用實體框架的 SQL 身份驗證:

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 類的詳細說明,該類也可用於構建動態連接字符串,然后按需傳遞此值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM