17

私は再利用可能なベースリポジトリクラスを作成しています。このクラスでは、開発者がを表すジェネリックを渡しObjectContext、ベースリポジトリが。を使用してそのインスタンスを作成しますActivator.CreateInstance。デバッグするときは、nugetパッケージを利用したいと思いますCommunityEFProviderWrappers.EFTracingProvider。したがって、オブジェクトコンテキストを設定するための私のコードは次のようになります。

    public void RenewDataContext()
    {
#if DEBUG
        // get the default container name
        var containerName = Activator.CreateInstance<T>().DefaultContainerName;

        // create an instance of the object context using EF Trace
        Context = (T)Activator.CreateInstance(typeof(T), EFTracingProviderUtils.CreateTracedEntityConnection(containerName));
        Context.EnableTracing();

#else
        Context = Activator.CreateInstance<T>();
#endif
    }

ObjectContext問題は、EFTracingProvider"指定されたスキーマが無効です。エラー:\ r \ n(0,0):エラー0175:指定されたストアプロバイダーが無効であるインスタンスを作成しようとすると、常に次のエラーがスローされることです。構成で見つかったか、無効です。」

containerNameをWeb構成の接続文字列の名前に置き換え、最初の名前を行わない場合は、Activator.CreateInstance<T>()正常に機能します。したがって、この問題は、最初のインスタンスを作成してから2番目のインスタンスを作成するという事実と関係があります。

これが私が試したことです:

  1. 最初のインスタンスを破棄してnullにします。
  2. 最初のインスタンスで接続を閉じます。
  3. 最初のインスタンスをusingステートメントに入れます。
  4. スタートアッププロジェクトのweb.configの接続文字列にObjectContextを含むアセンブリを明示的に定義します(Entity Framework Entity Connectionを使用する場合のMetadataException

ObjectContext開発者が一般的なタイプのANDと接続文字列の名前を渡さないようにしています。それは一種の冗長なようです。

だから私の質問は:オブジェクトコンテキストを表すジェネリックから接続名を取得し、それを使用してEFトレースによって生成されたEntityConnectionを使用してオブジェクトコンテキストのインスタンスを作成するにはどうすればよいですか?

私の質問は、この方法が機能しない理由についてであり、考えられる回避策についてではありません。

4

3 に答える 3

1

解決策は次のとおりです。構成ファイルに次のコードを追加します。

<system.data>
  <DbProviderFactories>
    <add name="EF Caching Data Provider"
         invariant="EFCachingProvider"
         description="Caching Provider Wrapper"
         type="EFCachingProvider.EFCachingProviderFactory, EFCachingProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=def642f226e0e59b" />
    <add name="EF Tracing Data Provider"
         invariant="EFTracingProvider"
         description="Tracing Provider Wrapper"
         type="EFTracingProvider.EFTracingProviderFactory, EFTracingProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=def642f226e0e59b" />
    <add name="EF Generic Provider Wrapper"
         invariant="EFProviderWrapper"
         description="Generic Provider Wrapper"
         type="EFProviderWrapperToolkit.EFProviderWrapperFactory, EFProviderWrapperToolkit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=def642f226e0e59b" />
  </DbProviderFactories>
</system.data>

メソッドで問題が発生しEFTracingProviderUtils.CreateTracedEntityConnectionます。構成ファイルで指定する必要がある.Net Framework Data Provider - EFTracingProviderを検索します。それが見つからない場合、その目的のためにそのような接続文字列を構築することはできません:

" metadata=reader://998e0526-8372-4bf9-83d3-949dececce96; provider=EFTracingProvider; provider connection string=\"wrappedProvider=;data source=.\SQLEXPRESS;attachdbfilename=|DataDirectory|\database.mdf; 統合セキュリティ = True; 接続タイムアウト = 30; ユーザー インスタンス = True; 複数のアクティブな結果セット = True; App=EntityFramework\"; "

メタデータ リーダーがこの接続文字列を指定していることがわかります。ここでは、EF が EFTracingProvider を見つけられない場合にスローされる MetadataException になります。サードパーティの方法の問題です。

次のメソッドを呼び出して、構成を変更せずに同じ結果を受け取ることができます。

EntityConnectionWrapperUtils.CreateEntityConnectionWithWrappers(containerName, new string[]{});
于 2013-03-18T10:22:37.960 に答える
0

私の友人は非常に単純なので気付かれず、その構成ファイルは同じプロジェクト ビュー (スタートアップ プロジェクト) の接続文字列ではありません。asp.net web.config になく、Windows フォームが app.config プロジェクトにない場合(表示) Windows フォーム (UI)。

于 2013-07-09T05:54:05.427 に答える
0

本当に直接的な答えではありません。

そのような構成が存在するというハードコードの仮定はお勧めしません。

(T)Activator.CreateInstance(typeof(T), EFTracingProviderUtils.CreateTracedEntityConnection(containerName));

EF 接続文字列を既定の名前で構成ファイルに保存する場合は、(単純な例を除いて) 非常にまれなケースです。接続文字列を受け入れるか、何らかの規則を適用する方が良いと思います。

ご参考までに。直接DbContext露出しません。最初DefaultContainerNameに取得する必要があります。ObjectContext

于 2013-02-20T10:22:58.153 に答える