Строка подключения ад в .NET / LINQ-SQL / ASP.NET - PullRequest
28 голосов
/ 25 октября 2008

У меня есть веб-приложение, которое содержит следующее:

  • Веб-проект (с файлом web.config, содержащим строку подключения, но без кода доступа к данным в веб-проекте)
  • Проект доступа к данным, использующий классы LINQ-SQL для предоставления сущностей пользовательскому интерфейсу веб-проекта (в этом проекте есть файл настроек и app.config - оба из которых имеют строки подключения)

При сборке и развертывании в каталоге Bin отсутствует файл настроек или app.config с доступом к данным .dll, но изменение строки подключения в файле web.config не приводит к соответствующему изменению базы данных - поэтому Строка подключения должна быть скомпилирована в DLL доступа к данным.

Мне нужен один файл конфигурации для всего моего развертывания - веб-сайт, библиотеки доступа к данным, все, что имеет одну строку подключения, которая используется. На данный момент, кажется, есть несколько строк подключения, которые используются или жестко закодированы повсеместно.

Как мне лучше разрешить этот беспорядок?

Спасибо за любую помощь.

Ответы [ 13 ]

14 голосов
/ 25 октября 2008

У меня никогда не было проблем с тем, что Уровень доступа к данным (DAL) может использовать строки подключения из моего файла web.config. Обычно я просто копирую раздел строк подключения из DAL и вставляю его в web.config. Я использую конструктор DBML для создания контекста данных.

Если это не сработает, вы можете указать строку подключения в конструкторе контекста данных. В вашем веб-проекте есть статический класс, который загружает ваши настройки, включая строки подключения, и когда вы создаете свой объект DAL (или контекст данных, если создаете его напрямую), просто передаете его конструктору.

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))
{
   ...
}
6 голосов
/ 25 октября 2008

Файл конфигурации для запускаемого проекта определит параметры конфигурации для всех включенных проектов. Например, если ваш веб-проект является начальным проектом, любая ссылка на «appSettings» будет искать настройки из web.config, включая ссылки на «appSettings» из вашего проекта доступа к данным. Поэтому скопируйте все параметры конфигурации из файла app.config проекта Data Access в файл web.config веб-проекта.

5 голосов
/ 25 октября 2008

Сверните свою собственную фабрику соединений на основе реестра:

  • добавить раздел реестра для вашего приложения в разделе ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ / [YOUR_COMPANY] / [YOUR_APP]
  • добавить строковое значение для ConnectionString
  • Научите вашу ConnectionFactory взломать соответствующий раздел реестра (в статическом конструкторе, а не при каждой загрузке страницы!).
  • экспортировать информацию реестра в виде файла .reg, добавить его в систему управления версиями, изменить и применить его при необходимости для настройки дополнительных компьютеров.

Pro:

  • Простота настройки
  • Строка подключения живет в одном месте
  • Нет в web / app.config, поэтому нет необходимости жестко кодировать параметры среды.
  • Нет в web / app.config, поэтому младший разработчик Джимми не может случайно сказать вашему производственному серверу взглянуть на базу данных DEV

Con:

  • Не сразу очевидно, что в реестре живут важные вещи, поэтому новым разработчикам понадобятся инструкции.
  • Дополнительный шаг при настройке новой машины развертывания
  • Реестр - oldskool. Младшие разработчики будут издеваться над вами.
4 голосов
/ 25 октября 2008

Спасибо за ответы.

Те из вас, кто говорит, что приложение будет использовать настройку в файле web.config, подходят для случаев, когда я ссылаюсь на него в своем собственном коде:

_connectionString = ConfigurationManager.AppSettings["ConnectionString"];

.. но есть другая проблема с LINQ-SQL datacontexts - я думаю, что они включают строки соединений в скомпилированную dll для использования в конструкторе без параметров. Как говорит тванофоссон, мне нужно создать текстовые данные, передав ссылку на строку подключения в файле web.config. Куда я попал в клубок:)

3 голосов
/ 23 апреля 2009

У меня тоже была небольшая борьба с этим вопросом. Я нашел решение, используя частичное определение класса c # и расширив datacontext, созданный дизайнером dbml. Это решение вполне похоже на ответ tvanfosson. Вам нужно создать частичный класс datacontext с конструктором по умолчанию, получающим ConnectionString из настроек, а в свойствах DC конструктора dbml установить соединение на None. Таким образом, строка подключения не будет скомпилирована в dll. Datacontext автоматически получит строку подключения из настроек строки подключения web.config. Я не проверял, работает ли это и с app.config, но я думаю, что он должен работать нормально.

Вот пример частичного класса DC:

namespace MyApplication {
    /// <summary>
    /// Summary description for MyDataContext
    /// </summary>
    /// 
    public partial class MyDataContext
    {
        public MyDataContext() :
            base(global::System.Configuration.ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString, mappingSource)
        {
            OnCreated();
        }
    }
}
3 голосов
/ 25 октября 2008

Ваше приложение будет использовать только записи конфигурации в файле web.config. Вы можете поместить настройки конфигурации dll в файл web.config, если они правильно структурированы. Мой пример специфичен для VB с использованием My Namespace, но он дает вам общее представление.

В паре configSections файла конфигурации вам потребуется запись:

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

Затем в части applicationSettings файла конфигурации вы помещаете записи для каждой dll:

    <applicationSettings>
      <YourAssembly.My.MySettings>
        <setting name="DebugMode" serializeAs="String">
            <value>False</value>
        </setting>
      </YourAssembly.My.MySettings>
    </applicationSettings>  
2 голосов
/ 15 августа 2010

Чтобы обезопасить себя от чего-либо в автоматически сгенерированном коде, переопределите информацию о соединении в методе OnCreated () контекста данных:

using System.Configuration;
namespace MyApplication 
{
    partial void OnCreated()
    {
        // attempt to use named connection string from the calling config file
        var conn = ConfigurationManager.ConnectionStrings["MyConnectionString"];
        if (conn != null) Connection.ConnectionString = conn.ConnectionString;
    }
}

Таким образом, dbml-дизайнер может выполнять соединения по-своему (что нехорошо вне веб-проекта), но вы получаете окончательный контроль над соединением при запуске приложения.

1 голос
/ 25 октября 2008

Вот один из способов взглянуть на это. Какой компонент должен принять решение о том, какую базу данных использовать? Вполне возможно, что база данных (или, по крайней мере, строка подключения) может измениться в будущем. Веб-сайт решает, какую базу данных использовать? Или DAL решает?

Если у вас есть базы данных dev, QA, UAT и prod, управление этими строками подключения имеет решающее значение.

Если веб-сайт решит, он должен передать строку подключения из своего web.config в DAL. Если веб-сайт не должен знать или заботиться о том, откуда поступают данные, тогда строка подключения принадлежит DAL.

0 голосов
/ 30 ноября 2010

Я знаю, что это старо, но вот как я это делаю (мне очень нравится @ Себа, но я этого не пробовал)

Предполагается, что ваш файл DBML находится в собственной библиотеке классов, что мне показалось наиболее удобным при совместном использовании сущностей и доступа к данным на нескольких веб-сайтах и ​​в других библиотеках классов. Предполагается также, что вы называли свою строку подключения одинаковой в каждом проекте. Я использую NAnt, чтобы установить это при развертывании в разных средах.

Я основал это на верхнем ответе выше @tvanfosson - слава этому парню.

  1. Создайте свой собственный базовый класс, производный от LinqDataContext

Вот код VB:

    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. Откройте файл DBML и в Свойствах добавьте указанное выше имя класса в свойство Базового класса.

Обратите внимание: если вы поместили пользовательский класс контекста данных в ту же сборку, просто включите имя класса, например, CustomDataContext.

Если они находятся в разных сборках, используйте полное имя, например, MyCo.MyApp.Data.CustomDataContext

  1. Чтобы обеспечить правильную работу компонента Designer, скопируйте строку подключения в файл app.config для библиотеки классов. Это не будет использоваться отдельно от IDE.

Вот и все.

Вам нужно будет назвать строку подключения одинаковой

По сути, вы заставляете контекст данных игнорировать информацию о соединении, заданную в файле DBML. Использование методов ConfigurationManager будет означать, что он выберет строку подключения из вызывающей сборки.

НТН

0 голосов
/ 25 октября 2008

Сверните свою собственную фабрику соединений на основе файлов .config:

  • Определение пользовательского раздела конфигурации для сопоставления пар ключ / строка подключения
  • Научите ваш ConnectionFactory прослушивать этот раздел конфигурации, используя имя хоста или имя машины в зависимости от ситуации
  • Заполните значения ключа / строки подключения для ваших различных серверов dev / qa / prod и поместите их в различные файлы app.config, web.config и т. Д.

Pro:

  • Все живет внутри проекта, поэтому никаких сюрпризов
  • Добавление дополнительной цели развертывания - операция копирования / вставки в файле .config

Con:

  • Делает для больших уродливых секций XML, особенно если у вас дюжина производственных серверов
  • Необходимо дублировать между проектами
  • Требуется изменение кода и повторное развертывание для добавления новой цели
  • Код должен знать о среде, в которой он будет жить
...