Connection string hell in .NET / LINQ-SQL / ASP.NET

后端 未结 13 1125
渐次进展
渐次进展 2021-01-30 14:29

I have a web application that comprises the following:

  • A web project (with a web.config file containing a connection string - but no data access code in the web pr
相关标签:
13条回答
  • 2021-01-30 14:43

    I know this is old but here's how I do it (I quite like @Seba's way but I haven't tried that)

    This assumes your DBML file resides in its own class library, which I've found it most convenient when sharing entities and data access across multiple websites, and other class libraries. It also assumes you've named your connection string the same in each project. I use NAnt to set this when I deploy to different environments.

    I based this on the top answer above from @tvanfosson - kudos to that guy.

    1. Create your own base class, which derives from LinqDataContext

    Here's the VB code:

        Imports System.Configuration
    
    Public Class CustomDataContextBase
        Inherits System.Data.Linq.DataContext
        Implements IDisposable
    
        Private Shared overrideConnectionString As String
    
        Public Shared ReadOnly Property CustomConnectionString As String
            Get
                If String.IsNullOrEmpty(overrideConnectionString) Then
                    overrideConnectionString = ConfigurationManager.ConnectionStrings("MyAppConnectionString").ConnectionString
                End If
    
                Return overrideConnectionString
            End Get
        End Property
    
        Public Sub New()
            MyBase.New(CustomConnectionString)
        End Sub
    
        Public Sub New(ByVal connectionString As String)
            MyBase.New(CustomConnectionString)
        End Sub
    
        Public Sub New(ByVal connectionString As String, ByVal mappingSource As System.Data.Linq.Mapping.MappingSource)
            MyBase.New(CustomConnectionString, mappingSource)
        End Sub
    
        Public Sub New(ByVal connection As IDbConnection, ByVal mappingSource As System.Data.Linq.Mapping.MappingSource)
            MyBase.New(CustomConnectionString, mappingSource)
        End Sub
    
    End Class
    
    1. Open your DBML file, and in the Properties, add the above class name to the Base Class property.

    Note, if you placed the custom data context class in the same assembly, simply include the class name, e.g. CustomDataContext.

    If they are in different assemblies, use the fully qualified name, e.g. MyCo.MyApp.Data.CustomDataContext

    1. To ensure the Designer stuff works properly, copy your connection string into the app.config file for the class library. This will not be used apart from in the IDE.

    That's it.

    You'll need to name your connection string the same

    What you are essentially doing is forcing the data context to ignore the connection info set in the DBML file. Using the ConfigurationManager methods will mean that it will pick up the connection string from the calling assembly.

    HTH

    0 讨论(0)
  • 2021-01-30 14:45

    I had a bit of a struggle with this issue too. I found a solution by using c# partial class definition and extending the datacontext created by dbml designer. This solution quite is similar to tvanfosson's answer. What you have to do is to create partial datacontext class with default constructor getting ConnectionString from settings and in dbml designer DC properties set connection to None. That way connection string will not be the compiled into dll. Datacontext will automatically get connection string from web.config connectionstring settings. I have not tested if this works with app.config also, but I think it should work fine.

    Here is sample of partial DC class:

    namespace MyApplication {
        /// <summary>
        /// Summary description for MyDataContext
        /// </summary>
        /// 
        public partial class MyDataContext
        {
            public MyDataContext() :
                base(global::System.Configuration.ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString, mappingSource)
            {
                OnCreated();
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-30 14:53

    You could also have the web application provide the connection string when it needs to use the Data Access project. You could make it part of the constructor.

    Also, you could could just write your own logic to load a connection string from an external file when the data access project makes it's calls.

    0 讨论(0)
  • 2021-01-30 14:54

    I've never had a problem with the Data Access Layer (DAL) being able to use the connection strings from my web.config file. Usually I just copy the connection strings section from the DAL and paste it into the web.config. I'm using the DBML designer to create the data context.

    If this won't work for you, you can specify the connection string in the data context constructor. In your web project have a static class that loads your settings, including your connection strings, and when you create your DAL object (or data context, if creating it directly) just pass it in to the constructor.

    public static class GlobalSettings
    {
        private static string dalConnectionString;
        public static string DALConnectionString
        {
           get
           {
               if (dalConnectionString == null)
               {
                  dalConnectionString = WebConfigurationManager
                                          .ConnectionStrings["DALConnectionString"]
                                            .ConnectionString;
               }
               return dalConnectionString;
           }
        }
    }
    ...
    
    using (var context = new DALDataContext(GlobalSettings.DALConnectionString))
    {
       ...
    }
    
    0 讨论(0)
  • 2021-01-30 14:55

    Your application will only use the config entries in the web.config file. You can put dll config setting in the web.config file as long as they are structure properly. My example is VB specific using the My Namespace, but it gives you the general idea.

    In the configSections paret of the config file you will need an entry:

    <configSections>
        <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="YourAssembly.My.MySettings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
        </sectionGroup></configSections>
    

    Then in the applicationSettings part of the config file you put the entries for each dll:

        <applicationSettings>
          <YourAssembly.My.MySettings>
            <setting name="DebugMode" serializeAs="String">
                <value>False</value>
            </setting>
          </YourAssembly.My.MySettings>
        </applicationSettings>  
    
    0 讨论(0)
  • 2021-01-30 14:56

    Roll your own ConnectionFactory based on .config files:

    • Define a custom config section to map key/connectionstring pairs
    • Teach your ConnectionFactory to sniff into that config section using hostname or machinename as appropriate
    • Populate key/connectionstring values for your various dev/qa/prod servers, and drop them into your various app.config, web.config etc. files.

    Pro:

    • All lives inside the project, so no surprises
    • Adding additional deployment target is a copy/paste operation in a .config file

    Con:

    • Makes for big ugly XML sections, especially if you have a dozen production servers
    • Needs to be duplicated between projects
    • Needs code change & redeploy to add new target
    • Code needs to know about the environment in which it will live
    0 讨论(0)
提交回复
热议问题