如何在多个实体数据模型之间共享连接字符串
本文关键字:之间 共享 连接 字符串 数据模型 实体 | 更新日期: 2023-09-27 18:31:57
我有一个项目,它有 4 个实体数据模型。为了构建它们,我不想在我的项目中保存连接字符串,我想将连接字符串存储在app.config
文件中并在我的模型之间共享。我该怎么做?
谢谢
首先假设 DbContext 和模型/数据库。
- 在 app.config 文件中保留生成的 EF 连接字符串不变。正如 Arthur 所说,它们包含 EF 元数据 (csdl/ssdl/msl) 的路径。模型设计者在开发过程中也会使用它们。
- 添加一个名为"共享连接"的存储连接字符串。这是生产中唯一需要修改的连接字符串。
- 创建一个派生自 DbContext 的基类,并从该类派生所有上下文。
- 在基类中显式创建默认 EF 连接。然后修改它以使用共享连接字符串,如下所示:
public class BaseContext : DbContext
{
public BaseContext(string nameOrConnectionString)
: base(CreateConnection(nameOrConnectionString), true)
{
}
private static EntityConnection CreateConnection(string connectionString)
{
// Create a (plain old database) connection using the shared connection string.
DbConnection dbConn = Database.DefaultConnectionFactory.CreateConnection(
ConfigurationManager.ConnectionStrings["SharedConnection"].ConnectionString);
// Create a helper EntityConnection object to build a MetadataWorkspace out of the
// csdl/ssdl/msl parts of the generated EF connection string for this DbContext.
EntityConnection wsBuilder = new EntityConnection(connectionString);
// Merge the specific MetadataWorkspace and the shared DbConnection into a new EntityConnection.
return new EntityConnection(wsBuilder.GetMetadataWorkspace(), dbConn);
}
}
派生上下文的代码不会更改,除非它们必须从 BaseContext 继承。这是一个更健壮的CreateConnection方法。它具有错误处理功能,并以添加应用程序设置为代价从代码中删除共享连接字符串的名称。
private static EntityConnection CreateConnection(string connectionString)
{
// Find the name of the shared connection string.
const string appSettingKey = "SharedConnectionStringName";
string sharedConnectionStringName = ConfigurationManager.AppSettings[appSettingKey];
if (string.IsNullOrEmpty(sharedConnectionStringName))
{
throw new Exception(string.Format(
"Shared connection not configured. " +
"Please add a setting called '"{0}'" to the '"appSettings'" " +
"section of the configuration file.", appSettingKey));
}
// Create a (plain old database) connection using the shared connection string.
ConnectionStringSettings backendSettings =
ConfigurationManager.ConnectionStrings[sharedConnectionStringName];
if (backendSettings == null)
{
throw new Exception(string.Format(
"Invalid connection string name '"{0}'" in appSetting '"{1}'"",
sharedConnectionStringName, appSettingKey));
}
System.Data.Common.DbConnection dbConn =
Database.DefaultConnectionFactory.CreateConnection(
backendSettings.ConnectionString);
// Create a helper EntityConnection object to build a MetadataWorkspace out of the
// csdl/ssdl/msl parts of the generated EF connection string for this DbContext.
EntityConnection wsBuilder = new EntityConnection(connectionString);
// Merge the specific MetadataWorkspace and the shared DbConnection into a new EntityConnection.
return new EntityConnection(wsBuilder.GetMetadataWorkspace(), dbConn);
}
你可以先使用代码。您必须在代码中为每个模型编写映射,但是使用相同的连接字符串非常容易 - 只需"name=MyConnectionStringName"
传递给 DbContext 构造函数即可。
将数据库优先与 EDMX 一起使用时,EF 连接字符串包含以下两个字符串:
- "存储连接字符串",提供有关如何连接到数据库的信息
- 描述模型的 EF 元数据的路径
由于每个模型的第二部分都不同,因此您需要有四个不同的连接字符串。
如果只想有一个连接字符串,则需要: - 以其他方式存储元数据信息 - 编写代码以加载元数据并创建元数据工作区 - 读取单个存储连接字符串并从中创建连接 - 同时使用连接和元数据工作区创建实体连接 - 使用 EntityConnection 创建 ObjectContext - 如果您使用的是 DbContext,请使用 ObjectContext 创建 DbContext
似乎很难相信编写所有这些重要的代码会比在 app.config 中仅包含四个连接字符串更好。
可以将 EF 连接字符串传递给 ObjectContext。如果您有多个模型,则可以将每个模型连接字符串放在 app.config 中,为每个模型提供一个密钥,并在需要时查找此密钥,并在实例化时将相应的字符串传递给上下文。