如何在多个实体数据模型之间共享连接字符串

时间:2012-04-22 09:47:33

标签: c# asp.net linq entity-framework c#-4.0

我有一个项目有4个实体数据模型。为了构建它们我不想在我的项目中保存连接字符串,我想在app.config文件中存储连接字符串并在我的模型之间共享它。我怎么能这样做?

感谢

3 个答案:

答案 0 :(得分:2)

首先假设DbContext和model / database。

  1. 保留app.config文件中生成的EF连接字符串。正如Arthur所说,它们包含EF元数据的路径(csdl / ssdl / msl)。它们也在模型设计师的开发过程中使用。
  2. 添加一个名为例如的商店连接字符串“SharedConnection”。这是唯一需要在生产中修改的连接字符串。
  3. 创建一个派生自DbContext的基类,并从该类派生所有上下文。
  4. 在基类中明确创建默认EF连接。然后修改它以使用类似的共享连接字符串:
  5. 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);
    }
    

答案 1 :(得分:1)

您可以使用Code First。您必须在代码中为每个模型编写映射,但是使用相同的连接字符串非常容易 - 只需将"name=MyConnectionStringName"传递给DbContext构造函数。

将Database First与EDMX一起使用时,EF连接字符串包含:

  • “商店连接字符串”,提供有关如何连接数据库的信息
  • 描述模型的EF元数据的路径

由于每个模型的第二部分不同,因此您需要有四个不同的连接字符串。

如果您只想拥有一个连接字符串,那么您需要:   - 以其他方式存储元数据信息   - 编写代码以加载元数据并创建MetadataWorkspace   - 读取您的单店连接字符串并从中创建连接   - 使用连接和MetadataWorkspace创建EntityConnection   - 使用EntityConnection创建ObjectContext   - 如果您正在使用DbContext,则使用ObjectContext创建DbContext

似乎很难相信编写所有这些非平凡的代码比在app.config中只有四个连接字符串更好。

答案 2 :(得分:0)

您可以将EF连接字符串传递给ObjectContext。如果您有多个模型,可以将每个连接字符串放在app.config中,为每个模型添加一个键,并在需要时查看它,并在实例化时将相应的字符串传递给上下文。