質問

次のもので構成されるWebアプリケーションがあります。

  • Webプロジェクト(接続文字列を含むweb.configファイル-ただし、Webプロジェクトにはデータアクセスコードはありません)
  • LINQ-SQLクラスを使用してエンティティをWebプロジェクトUIに提供するデータアクセスプロジェクト(このプロジェクトには設定ファイルとapp.configがあり、どちらにも接続文字列があります)

ビルドしてデプロイするとき、データアクセス.dllのBinディレクトリに設定ファイルまたはapp.configはありませんが、web.configファイルの接続文字列を変更しても、それに応じてデータベースは変更されません。接続文字列は、データアクセスdllにコンパイルする必要があります。

必要なのは、展開全体(Webサイト、データアクセスdll、すべて)の1つの構成ファイルで、使用される接続文字列が1つあります。現時点では、あちこちで複数の接続文字列が使用またはハードコーディングされているようです。

この混乱を解決するにはどうすればよいですか

ご協力ありがとうございます。

役に立ちましたか?

解決

web.config ファイルの接続文字列を使用できる Data Access Layer (DAL)で問題が発生したことはありません。通常、DALから接続文字列セクションをコピーして、 web.config に貼り付けます。 DBMLデザイナーを使用してデータコンテキストを作成しています。

これがうまくいかない場合は、データコンテキストコンストラクターで接続文字列を指定できます。 Webプロジェクトには、接続文字列を含む設定を読み込む静的クラスがあり、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))
{
   ...
}

他のヒント

スタートアッププロジェクトの構成ファイルは、含まれるすべてのプロジェクトの構成設定を定義します。たとえば、Webプロジェクトがスタートアッププロジェクトの場合、" appSettings"への参照は、 web.configから設定を探します。これには、「appSettings」への参照が含まれます。データアクセスプロジェクトから。そのため、構成設定をデータアクセスプロジェクトのapp.configからWebプロジェクトのweb.configにコピーします。

レジストリに基づいて独自のConnectionFactoryをロールします:

  • SOFTWARE / [YOUR_COMPANY] / [YOUR_APP]の下にアプリケーションのレジストリキーを追加します
  • ConnectionStringの文字列値を追加
  • ConnectionFactoryに適切なレジストリキーをクラックするように指示します(すべてのページが読み込まれるのではなく、静的コンストラクターで!)。
  • レジストリ情報を.regファイルとしてエクスポートし、ソース管理に追加し、必要に応じて変更して適用し、追加のマシンをセットアップします。

長所:

  • セットアップが簡単
  • 接続文字列は単一の場所に存在します
  • web / app.configにはないため、環境固有の設定をハードコードする必要はありません。
  • web / app.configにはないので、Juniy Dev Jimmyは誤って運用サーバーにDEVデータベースを調べるように指示することはできません

コン:

  • 重要なものがレジストリに存在することはすぐには明らかではないため、新しい開発者は指示が必要になります。
  • 新しい展開マシンを構成する際の追加手順
  • レジストリはoldskoolです。ジュニア開発者があなたをock笑します。

回答ありがとうございます。

アプリがweb.configの設定を使用すると言う人は、自分のコードでそれを参照するインスタンスに適しています:

_connectionString = ConfigurationManager.AppSettings["ConnectionString"];

..しかし、LINQ-SQLデータコンテキストには別の問題があります-パラメーターレスコンストラクターで使用するために、コンパイルされたdllに接続文字列が含まれていると思います。 tvanofossonが言うように、web.configの接続文字列への参照を渡すことにより、データコンテキストを作成する必要があります。これは私がもつれになっていた場所です:)

私もこの問題に少し苦労しました。 c#部分クラス定義を使用して、dbmlデザイナーによって作成されたデータコンテキストを拡張することで解決策を見つけました。このソリューションは、tvanfossonの答えに非常に似ています。あなたがしなければならないのは、設定からConnectionStringを取得し、dbmlデザイナーのDCプロパティで接続を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();
        }
    }
}

アプリケーションは、web.configファイルの構成エントリのみを使用します。 dll構成設定は、適切に構造化されている限り、web.configファイルに配置できます。私の例は、My Namespaceを使用したVB固有ですが、一般的なアイデアを提供します。

configファイルの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>  

自動生成されたコード内のあらゆるものから安全に保つには、データコンテキストの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デザイナは接続関連の処理を行うことができます(Webプロジェクトの外部ではうまくありません)が、アプリケーションの実行時に接続の最終的な制御を取得します。

これを見る1つの方法があります。どのコンポーネントがどのデータベースを使用するかを決定する必要がありますか?データベース(または少なくとも接続文字列)が将来変更される可能性があります。 Webサイトは使用するデータベースを決定しますか?または、DALが決定しますか?

dev、QA、UAT、およびprodデータベースがある場合、これらの接続文字列を管理することが重要です。

Webサイトが決定した場合、web.configからDALに接続文字列を渡す必要があります。 Webサイトがデータの送信元を認識または気にする必要がない場合、接続文字列はDALに属します。

パラメーターとして列挙型を取り、完全な形式の接続オブジェクトを返すConnectionFactoryオブジェクトを定義する方法はどうですか?

データアクセスプロジェクトを使用する必要がある場合、Webアプリケーションに接続文字列を提供させることもできます。コンストラクタの一部にすることもできます。

また、データアクセスプロジェクトが呼び出しを行うときに、外部ファイルから接続文字列をロードする独自のロジックを記述することもできます。

完璧な世界では、データレイヤーをリファクタリングして、System.Configurationまたは関連するコンストラクター/ファクトリー経由で構成設定を取得すると思います。つまり、暗黙の構成ソースを再配線するか、ホスト/コンシューマから明示的に接続を設定する必要があります。これらのタイプの定数を集中化する別の関連パターンは、読み取り専用プロパティを静的ヘルパークラスにスローし、そのクラスに設定などからの実際の解決を管理させることです。

これをエレガントに行う方法の良い例を示していると思うのは、NHibernateとその構成/マッピング管理です。確かに、それは少しXML地獄であり、Fluent NHibはより糖度が高いですが、実際のサンプルのほとんどは、サポートするアセンブリと実行中のアセンブリの構成を調整する方法を示しています。

.configファイルに基づいて独自のConnectionFactoryをロールします:

  • カスタム設定セクションを定義して、キー/接続文字列のペアをマッピングします
  • 必要に応じてホスト名またはマシン名を使用して、その構成セクションをスニッフィングするようにConnectionFactoryに指示します
  • さまざまなdev / qa / prodサーバーのキー/接続文字列値を入力し、それらをさまざまなapp.config、web.configなどのファイルにドロップします。

長所:

  • すべてがプロジェクト内にあるため、驚くことはありません
  • 追加のデプロイメントターゲットの追加は、.configファイルでのコピー/貼り付け操作です

コン:

  • 大きないXMLセクションを作成します。特に、数十の実稼働サーバーがある場合は
  • プロジェクト間で複製する必要がある
  • コードの変更が必要&amp;再デプロイして新しいターゲットを追加します
  • コードは、それが存在する環境について知る必要があります

これは古いことは知っていますが、ここではその方法を説明します(@Sebaの方法は非常に好きですが、試したことはありません)

これは、DBMLファイルが独自のクラスライブラリに存在することを前提としています。これは、複数のWebサイトや他のクラスライブラリでエンティティとデータアクセスを共有するときに最も便利であることがわかりました。また、各プロジェクトで接続文字列に同じ名前を付けていることを前提としています。さまざまな環境に展開するときに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メソッドを使用すると、呼び出し元のアセンブリから接続文字列が取得されます。

HTH

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top