0

EFプロジェクトにリポジトリパターンを使用しようとしています。ユーザーは、ログオンする3つの別個の(ただし構造的に同一の)データベースから1つを選択できます(トレーニング用に1つ、テスト用に1つ、本番用に1つあります)。

現在、EF 4実装を使用しており、ADO.NetEntityObjectGeneratorを介してT4を生成しています。リポジトリの基本クラスは次のようになります。

public class RepositoryBase<C> : IDisposable
    where C : ObjectContext, new()
{
    private C _DataContext;

    public virtual C DataContext
    {
        get
        {
            if (_DataContext == null)
            {
                _DataContext = new C();
            }
            return _DataContext;
        }
    }

    //other code cut for brevity...
}

私たちが望んでいるのは、「_ DataConext = newC();」を変更する機能だと思います。実行時に生成される接続文字列を使用して適切なデータベースを指すことができるようにするための行。残念ながら、次のように接続文字列を渡します。_DataConext = new C(connectionString); は許可されておらず、次のメッセージが表示されます。「型パラメーターで使用される「新規」に引数を渡すことはできません。」

model.ttファイルのコードの背後にあるのは、3つのコンストラクターがあることです。デフォルトのパラメーターなしのコンストラクター、EntityConnectionパラメーターを持つコンストラクター、および接続文字列パラメーターを持つ3番目のコンストラクター(使用するコンストラクター)です。

問題は、これをどのように行うかです。どんな助けでも大歓迎です!

4

2 に答える 2

1

問題は、ジェネリック型のパラメーターでコンストラクターを指定することです。これは許可されていません。最初の解決策は、反射を使用することです。定義されているコンストラクターがわかっている場合:

public virtual C DataContext
{
    get
    {
        if (_DataContext == null)
        {
            _DataContext = (C)Activator.CreateInstance(typeof(C), new object[]{ connectionString });
        }
        return _DataContext;
    }
}

より良い解決策は、Cのインスタンスをリポジトリのコンストラクターに渡すことです。

それが役に立てば幸い

于 2012-06-07T14:01:11.323 に答える
0

新しいObjectContext汎用インスタンスの作成について好奇心を持ってこのスレッドに参加できますか?Activatorを使用せずにCreateContextメソッド(下記)を使用すると、どの接続を指定しても、「デフォルト」の接続文字列を使用して新しいインスタンスが作成されます。代わりにActivatorを使用すると、正しく検索して作成することができますが、私は迷子になっています...

私のapp.configには両方がありますが、edmxの作成中に作成されたもののみを使用します。

    /// <summary>
    /// Base repository
    /// </summary>
    public RepositoryBase(Connection.ConnectionManagerBase connectionmanager)
    {
        this.pContext = this.CreateContext(connectionmanager, (x => new C()));
        this.ContextObjectSet = this.pContext.CreateObjectSet<T>();
    }

    /// <summary>
    /// Create context with connection string
    /// </summary>
    /// <param name="connectionmanager">Connection manager</param>
    /// <param name="factory">Factory context</param>
    /// <returns>Instance</returns>
    private C CreateContext(Connection.ConnectionManagerBase connectionmanager, Func<string, C> factory)
    {
        // this create instance with correct connection
        return (C)Activator.CreateInstance(typeof(C), new object[] { connectionmanager.ConnectionString }); 
        // this use the "default" connection, no matter what is in connectionmanager.ConnectionString
        return factory(connectionmanager.ConnectionString);
    }
于 2012-06-24T10:42:36.097 に答える