2013-08-20 14 views
7

私は最近Entity Framework 5に切り替えました。現在、既存のデータベースからPOCOクラスを生成したいと思います。遅延ロードと変更追跡の両方が必要です。したがって、すべてのスカラープロパティは、ナビゲーションプロパティと同様に仮想でなければなりません。既存のデータベースからPOCOプロキシを生成する方法

新しいADO.Netエンティティデータモデルを追加すると、.edmxファイルとその他の.csと.ttファイルで終了します。

最初に、生成されたPOCOクラスがデフォルトで変更トラッキングプロキシの要件を満たさない理由、つまりスカラープロパティが仮想ではないのだろうかと思います。

第2に、プロキシ対応のpocoクラスをどのように生成できますか?

PS:私はスラウマの答えを最高と唯一の答えとして受け入れましたが、私はそれの最初の部分に同意しません。制限とパフォーマンス:プロキシ対応するエンティティの制限について

  • :ここ

    Slaumaは約2プロキシの問題を語る私の議論はある クラスがエンティティによってDBまず方法で生成された場合フレームワークでは、変更追跡プロキシを有効にするためにクラスが従わなければならないルールは、それらが制限的ではないのでそれほど重要ではありません。ナビゲーションコレクションがIListかHashSetかどうかは本当に気になりますか?制限について話すことは、アプリケーション内にperiorの設計されたクラスがあり、そこからテーブルを生成する場合にのみ有効です。

  • 複雑なプロパティは、DBでは最初にサポートされていません。だから私たちは議論から除外することができます。 perfomranceについて

  • :私が研究している the addressed articleでも他のいくつかの実験では、これまでの結果は、スナップショットの賛成でプロキシを拒否することは非常に説得力がありません。最初に、実験は多数の実体a.k.a 10,000で行われた。アプリケーション(データベースではない)のバッチ処理が多数のエンティティで機能することはありえませんが、ストアドプロシージャなどのより良いアプローチが想定されています。 第2に、アプリケーションの種類とニーズに応じて、通常、リポジトリパターンが実装され使用されている場合など、いくつかのエンティティを処理します。プロキシとスナップショットのパフォーマンスに違いはありません。興味深いことに、対処された実験では、プロパティに同じ値を再割り当てすることは、プロキシのパフォーマンスが劇的に低下する唯一のケースでした。しかし、誰がこれを本当にしていますか?変更トラッカーに繰り返し通知するのを避けることは非常に簡単です。この場合も、多数のエントリーが処理されるときに重大な問題が発生します。

答えて

4

デフォルトで生成されたPOCOクラスが が仮想ではない、変更追跡プロキシの要件を満たしすなわちスカラープロパティはありません、なぜ第一に、私は疑問に思います。

デフォルトの変更追跡戦略としては、変更追跡プロキシを使用することはお勧めできません。それはthis blog postで詳細に説明されています。本質的に、変更追跡プロキシを使用する主な理由は、スナップショットベースの変更追跡と比較してパフォーマンスが優れていることが常に保証されているとは限らず、場合によってはさらに悪化します。スカラプロパティを含む - -

は、過去にはPOCOエンティティを生成したT4テンプレートは確か すべてプロパティマーク virtualなどをし、プロキシベースの変更の追跡のためのエンティティを用意しました。ブログに記載された理由により、これは上記のブログ記事の下の this commentに記載されているように、EF 5のDbContextジェネレータを含む新しいテンプレートで変更されています。現在のところ、ナビゲーションプロパティのみが virtualとマークされていますが、遅延ロードを許可するスカラープロパティではなく、変更追跡プロキシでは不十分です。

第2に、プロキシ対応のpocoクラスを生成するにはどうすればよいですか?

私はこれを行うだろう使用可能な任意のT4テンプレートを認識していないけど、virtualとしてもスカラプロパティをマークするために、既定のテンプレートを変更することは非常に簡単です:

  • プロジェクトでは、あなたが拡張子が.ttの2つのファイル(YourModelContainer.ttYourModelContainer.Context.tt)が必要です。 YourModelContainer.ttファイルを開きます。このファイルには

  • あなたはメソッドが呼び出されProperty見つける:

    public string Property(EdmProperty edmProperty) 
    { 
        return string.Format(
         CultureInfo.InvariantCulture, 
         "{0} {1} {2} {{ {3}get; {4}set; }}", 
         Accessibility.ForProperty(edmProperty), 
         _typeMapper.GetTypeName(edmProperty.TypeUsage), 
         _code.Escape(edmProperty), 
         _code.SpaceAfter(Accessibility.ForGetter(edmProperty)), 
         _code.SpaceAfter(Accessibility.ForSetter(edmProperty))); 
    } 
    

    変更

     Accessibility.ForProperty(edmProperty), 
    

    ...へ...

     AccessibilityAndVirtual(Accessibility.ForProperty(edmProperty)), 
    
  • ...とライン

これだけです。

あなたがそれに精通していない場合でも、第2の種類のDatabase-Firstアプローチがあります。これはReverse Engineering an existing database to a Code-First modelです。このアプローチはT4テンプレートをまったく使用せず、コードファーストモデルとFluent APIマッピングを持つコンテキストを作成します。モデルクラスをカスタマイズして拡張する場合(手動でvirtual修飾子を追加することもできます)、将来、コードファーストワークフロー(およびコードファーストマイグレーション)を続行してデータベーススキーマを更新および展開したい場合に便利です。

+0

ありがとうございました。私はあなたの答えの最初の部分に同意せず、私は議論を反映するために私の質問を更新しました。しかし、2番目の部分は非常に便利でした。私はCode-Firstモデルを認識していますが、それは私の心配ではありません。 – Alireza

+0

@Alireza:部分的に私は第1部のあなたの評論家に同意します。私は自分自身の変更追跡プロキシのファンであり(http://stackoverflow.com/a/7112470/270591)、それらは私のプロジェクトの1つで命を救ってくれました。 Arthur Vickerの記事が公開されたあと、私はちょっと注意を払いました。最初の部分は、新しいt4テンプレートがPOCOを作成するときにスカラープロパティから 'virtual'修飾子を削除した理由を説明するEFチームの視点の引用です。 – Slauma

+1

おそらく彼らはあなたが言ったように推論していたかもしれませんが、依然として代理人を再び有効にする方法を教えることができました。これはマイクロソフトによって黙って行われ、プロキシにバグがあると思うかもしれません。 – Alireza

関連する問題