2011-03-03 1 views
3

Contentにタグを指すContentTagがある多対多関係があります。エンティティに関連する[Include]属性を設定してプロパティを作成しました。クエリがテーブルを結合するときに子エンティティが読み込まれない

私がObjectContext.Contents.Include("ContentTags.Tag")を列挙して書くと、ContentTagsとTagが期待通りに含まれています。しかし、私はコンテンツのエンティティからコンテンツタグが欠落していますが、結合を使用しています:

var contentsForTag = 
    from c in ObjectContext.Contents.Include("ContentTags.Tag") 
    join ct in ObjectContext.ContentTags on c.Id equals ct.ContentId 
    join t in ObjectContext.Tags on ct.TagId equals t.Id 
    where t.Name.ToLower().Contains(lowerTag) 
    select c; 

何が起こっているのですか?

答えて

2

私はこれがなぜ起こっているのか分かりませんが、私はそれが矛盾のためだと思います。 結合では、lowerTagを含むタグのみを読み込む必要がありますが、Includeではすべてのタグを読み込む必要があることが示されています。私はEFがこれを解決できないと考えているので、それが含まれていないのです。あなたは、参加なしであなたのクエリを書くことができるはずです

var contentsForTag = 
    from c in ObjectContext.Contents.Include("ContentTags.Tag") 
    where c.ContentTags.Any(ct => ct.Tag.Name.ToLower().Contains(lowerTag)) 
    select c; 
+0

ああ、私が探していたものです。クエリのフォーマットもかなり良いです。将来の使用のためにAny拡張メソッドをメモリにコミットする必要があります。 – Phill

0

「遅延ロード」と「eager-load」の違いに似ています。 Contentクラスのタグのコレクションは、子テーブルに格納されます。 EFを含む多くのORMは、コレクションを必要とするかどうかわからず、そうでない場合は帯域幅の浪費になるので、コレクションやその他の多対1の参照を「遅延ロード」しようとします。ただし、これは、取得したインスタンスでタグが使用できないことを意味します。 L2Eに、本当にタグが必要であることを伝えるには、コンテキストを構築するときに子参照を「熱心に」走査するように指定します。

1

次のことを試してみてください。

var anonType = 
    from c in ObjectContext.Contents 
    join ct in ObjectContext.ContentTags on c.Id equals ct.ContentId 
    join t in ObjectContext.Tags on ct.TagId equals t.Id 
    where t.Name.ToLower().Contains(lowerTag) 
    select new { Contents = c, ContentTags = ct, Tags = t }).AsEnumerable(); 

IList<Contents> contentsForTag = anonType.Select(c => c.Contents).ToList(); 

匿名型EFに関連するすべてのテーブルを削除した場合は、あなたが実際にその情報のすべてを必要とし、それを戻すことを理解します。 EFが自動修正の世話をするということは、すべての関係が維持されることを意味します。サンプルの最後の行は、匿名型から強く型付けされたリストに目的のオブジェクトを抽出するだけですが、残りのグラフはまだ生き残っています。

関連する問題