2

Aggregate Root パターンをドメインに適用しようとしています。POCO Entity GeneratorでEntity Framework 4を使用しています。

2 つのエンティティがあります。 MailingTask EmailLog 1 対多の関係があります。(MailingTask には多くの EmailLogs があります)。EF4 は、MailingTask でナビゲーション プロパティを生成します。

public virtual ICollection<EmailLog> EmailLogs

私のモデル内では、EmailLogs に直接アクセスしたくはありません。常に親の MailingTask を介してアクセスします。これは、次の方法で実施されます。

  • MailingTask リポジトリしかないため、EmailLogs テーブルを直接クエリすることはできません。
  • このナビゲーション プロパティのみを介して EmailLogs を取得します。

MailingTask の EmailLogs の数を数える必要がある場合があります。これは、ナビゲーション プロパティで LINQ を使用することによって実現されます。

mailingTask.EmailLogs.Count();

ただし、これは (データベース サーバーではなく) アプリケーション側で実行されます。(そして、MailingTask 用の EmailLogs がたくさんあるので、非常に高価です。) この動作に関するいくつかの投稿を読んだところ、EF4 ナビゲーション プロパティを IQueryable (データベース側で実行) として使用できないようです。ナビゲーション プロパティにアクセスすると、EF4 はメモリ内のすべての列を含むすべてのエントリを読み込み、メモリ内の LINQ 式を適用します。Count() ステートメントの場合、これは非常に厄介です。

この特殊なクエリに対応するには、モデルを変更する必要があると思います (クエリ機能を備えた EmailLogsRepository を追加する可能性があります)。私にとっては、EF4 は Aggregate Root パターンをうまくサポートしていないようです。それとも、Aggregate Root パターンと、EF4 に関してそれをどのように実装する必要があるかについて何かが欠けているかもしれません...

誰かがこの状況に遭遇し、これを解決できましたか? nHibernate または別の ORM はこれをより適切にサポートしていますか?

4

1 に答える 1

0

NHibernate はCount()、SQL の「Select COUNT(*) ..」クエリにマップされ、すべてのエンティティを実体化する必要がないため、「ネイティブに」サポートします。これは、EF が同じクエリで行うことです。

Entity Framework の場合、同じことを達成するための回避策があります。詳細はこちら. カウントのクエリは次のようになります。

int logCount = context.Entry(mailingTask)
                      .Collection(p => p.EmailLogs)
                      .Query()
                      .Count();

ナビゲーション プロパティ / を直接操作できないため、この 1 つのクエリに対してモデルを変更する必要があります。Count()これは大きな欠点であり、EF でできるだけ早く修正する必要があります。

于 2011-05-09T15:53:04.953 に答える