5

私は次のようなEFモデルの一部です。

ここに画像の説明を入力してください

概要:

  • 場所には多くの投稿があります
  • Postは抽象クラスです
  • ディスカッションは投稿から派生します
  • ディスカッションには多くのコメントがあります

今、私が達成しようとしているクエリ:

それらのディスカッションに関連するディスカッションやコメントなど、ロケーションID1234に関する情報を取得します。

私はこのような議論とコメントを得ることができます:

var discussions = ctx.Posts
                     .OfType<Discussion>()
                     .Include(x => x.Comments)
                     .ToList();

しかし、 LocationエンティティのPostsナビゲーションに基づいて取得できないようです。

私はこれを試しました:

var locationWithDiscussionsAndComments = ctx
                    .Locations
                    .Include(x => x.Posts
                                   .OfType<Discussion>()
                                   .Select(y => y.Comments))
                    .SingleOrDefault();

どちらがコンパイルされますが、エラーが発生します:

System.ArgumentException:インクルードパス式は、エンティティによって定義されたプロパティを参照する必要があります。オプションで、ネストされたプロパティまたはSelectの呼び出しも参照する必要があります。パラメータ名:パス

何か案は?私はおそらく投稿から「後方」に行くことができます:

var locationWithDiscussionsAndComments = ctx
                   .Posts
                   .Include(x => x.Location)
                   .OfType<Discussion>()
                   .Include(x => x.Comments)
                   .Where(x => x.LocationId == 1234)
                   .Select(x => x.Location)
                   .ToList();

しかし、それは私のリポジトリの観点からは厄介で意味的に間違っています(場所に関する情報を取得するために投稿リポジトリを通過する必要はありません)。

何か案は?

編集

それで、それについてもっとよく考えた後、私はそれOfType<T>がフィルター操作であることに気づきました。ご存知のように、EFは積極的な読み込みによるフィルタリングをサポートしていません。唯一のオプションは、すべてを取得するか、匿名タイプの射影を使用することです。

メタデータが多すぎるため、すべてを取得することはできません。だから私は匿名型の投影を試みています。

4

1 に答える 1

6

新しいQueryメソッドは次のことに役立ちます。

var location = context.Locations.SingleOrDefault();

context.Entry(location)
       .Collection(l => l.Posts)
       .Query()
       .OfType<Discussion>()
       .Load();


リポジトリの実装:

この新しいメソッドを活用するクラスに、新しいLoadPropertyジェネリックメソッドを追加できます。Repository<T>QUery

public void LoadProperty<TElement>(T entity, 
        Expression<Func<T, ICollection<TElement>>> navigationProperty,
        Expression<Func<TElement, bool>> predicate) where TElement : class
{
    _context.Set<T>().Attach(entity);

    _context.Entry(entity)         
            .Collection(navigationProperty)
            .Query()
            .Where(predicate)
            .Load();
}

LoadPropertyメソッドの使用:

Location location = _locationRepository.Find(1);
_locationRepository.LoadProperty(location, l => l.Posts, p => p is Discussion);
于 2011-03-04T16:14:07.517 に答える