Entity Framewor学習ノート(include+where)

2263 ワード

サブクエリでフィルタリングをしたい場合はどう書きますか?
IEnumerable<Product> products = db.products.Include(p => p.colors.Where(c => c.id == 5)).ToList();

product - color , 1-n
そう思うかもしれませんが、結果はerrorです.「The Include path expression must refer to a navigation property defined on the type.Use dotted paths for reference navigation properties and the Select operator for collection navigation properties.」
正しい方法は匿名のオブジェクトを使用して包装することです
var products = db.products.Include(p => p.colors).Select(p => new

{

    id = p.id,

    colors = p.colors.Where(c => c.id == 5)

    //                         

}).ToList();

この方法は可能だが欠点が多い.例えば、属性=valueの山を書き、IEnumerableではなくIEnumerable<匿名オブジェクト>である.
だから私たちはこのように書くべきです
IEnumerable<Product> products = db.products.Include(p => p.colors).Select(p => new

{

    Product = p, 

    colors = p.colors.Where(c => c.id == 5)                  

    //        

}).ToList().Select(p => p.Product).ToList();

参照先:http://stackoverflow.com/questions/25276978/ef-6-add-where-clause-to-an-include-with-navigation-property
君は少し疑問に思っているかもしれないが,どうしてこのように書いてもいいのか.
実は原理は簡単です. 
var product = db.products.ToList();

var colors = db.colors.ToList();

Color c = product.First().colors.First();

上の3番目の文はcolorを得ることができて、原理はcolor sが要求されて帰ってきた後に、それは自動的にproductに記入します.colors値、base on彼のforeign keyをリンクします.
EFの役割ドメイン内であれば、すべての関係が埋め込まれる.