2011-12-16 15 views
2

質問のタイトルに何を書き込むのか分かりませんでした。ここに私のサンプルがあります。あなたはFOOSとバーの両方が非アクティブ(Active = false)として設定することができます見ることができるようにLinqアクティブな子エンティティのクエリ

public class Foo 
{ 
    public bool Active {get; set;} 
    public ICollection<Bar> Bars {get; set;} 
} 

public class Bar 
{ 
    public bool Active {get; set;} 
} 

:私は次のようにバーのコレクションを持っているのFooクラスを持っています。私はすべてのアクティブなFooをそのアクティブバーで返すサービス(RIA)を書いていません。
は、これは私がこれまで持っているものです。

public IQueryable<Foo> GetFoos() 
{ 
    return ObjectContext.Foos.Where(f => f.Active) 
          .Include("Bars"); 
} 

事は上記のクエリは、すべての単一のBarを持つすべてのアクティブFooを返すということですので、どのように私はのみアクティブBarsが含まれていますか?

答えて

1

IncludeメソッドはLazyLoadingの一部です。レイジーローディングは、すべてまたは無しのいずれかであるため、EFにいくつかのバーのみをロードするように指示することはできません。

あなたがやろうとすることができるどのような、しかし、結果として匿名オブジェクトを使用している:

context.Foos 
.Where(f => f.Active) 
.Select(f => new { Foo = f, Bars = f.Bars.Where(b => b.IsActive }); 
+0

シンプルで効果的な...どうもありがとうございました! – sebagomez

1

EFは、EFが動作するように設計されているという考え方に反しているので、このように簡単にはできません。 FooエンティティのBarsコレクションに「アクティブな」Barエンティティのみが含まれるようにこのクエリを記述するのが簡単だった場合、各Fooエンティティはデータベースの状態の正確なモデルではありません。

一方、(Fooエンティティを直接取得するのではなく)投影を使用してクエリを記述すると、柔軟性が向上します。たとえば、あなたがこのようクエリを記述できます。この時点で

var query = 
    from f in ObjectContext.Foos 
    where f.Active 
    select new { Foo = f, ActiveBars = f.Bars.Where(b=>b.Active)} 

あなたFooエンティティと再度関連付けるアクティブBarエンティティにforeachループを書くことができます:

var results = query.ToList(); 

foreach (var r in results) 
    r.Foo.Bars = r.ActiveBars; 

そして、最後にLINQクエリをローカルで実行して結果を返します。

return (from r in results select r.Foo).ToList(); 

私は、私はちょうどディスプレイオンリーのシナリオでうまくいくだろうと輪郭を描いたばかりですが、このようにして検索されたエンティティを更新しようとするのは躊躇します。

関連する問題