2014-02-28 55 views
0

我有類:如何在Linq where子句中引用has-many-through關係?

  • COMPONENTTYPE
    • ID
    • 名稱
    • ...
  • 組件
    • 編號
    • ComponentTypeID
    • ...
  • RigAction
    • ID
    • RigActionTypeID(指向下方RigActionType)
    • 的ComponentID(指向上述成分)
  • RigActionType
    • 名稱
    • ...

我試圖用RigActionTypeIDComponentTypeID查詢所有RigActions和我使用LINQ的where()方法掙扎。我想出了下面代碼中的第一部分,但在檢查第二部分中的componentTypeID屬性時遇到了問題。

var actions = db.RigActions 
    .Where(ra => ra.RigActionTypeID == rigActionTypeID) 
    .Where(ra => ra.Components.SelectMany(c => c.ComponentTypeID == componentTypeID)); 
+0

你需要SelectMany嗎?如何:var actions = db.RigActions.Where(ra => ra.RigActionTypeID == rigActionTypeID).Where(ra => ra.Components.ComponentTypeID == componentTypeID)); – MikeH

+0

@MikeH我可能只是有這個定義錯誤,但在這種情況下'ra.Components'是一個EntitySet - 所以調用'.ComponentTypeID'將調用它的集合,而不是實體。有沒有解決方法? – drewwyatt

+0

您發佈的代碼是否正在編譯? SelectMany似乎不應該工作。 – MikeH

回答

1

SelectMany變平枚舉枚舉至少一個component。如果您的LINQ查詢的目的是要產生一種特定類型的組件,然後這應該這樣做:

var components = db.RigActions 
    .Where(ra => ra.RigActionTypeID == rigActionTypeID) 
    .SelectMany(
     ra => ra.Components 
      .Where(c => c.ComponentTypeID == componentTypeID) 
    ); 

但是,如果你打算返回具有特定類型的至少一個組件操作,那麼這樣做:

var actions = db.RigActions 
    .Where(ra => ra.RigActionTypeID == rigActionTypeID && 
       ra.Components.Any(c => c.ComponentTypeID == componentTypeID) 
    ); 

如果您需要具有特定類型的唯一部件動作做:

var actions = db.RigActions 
    .Where(ra => ra.RigActionTypeID == rigActionTypeID && 
       ra.Components.All(c => c.ComponentTypeID == componentTypeID) 
    ); 

如果您需要選擇行動,只保留了一些在同一時間的行動內的部件,然後做這個(假設ComponentsList<>不是隻讀):

var actions = db.RigActions 
    .Where(ra => ra.RigActionTypeID == rigActionTypeID) 
    .Select(ra => { 
     ra.Components = ra.Components 
      .Where(c => c.ComponentTypeID == componentTypeID) 
      .ToList(); 
     return ra; 
    }); 

如果該列表是隻讀的,做到這一點:

var actions = db.RigActions 
    .Where(ra => ra.RigActionTypeID == rigActionTypeID) 
    .Select(ra => { 
     ra.Components.RemoveAll(c => c.ComponentTypeID != componentTypeID); 
     return ra; 
    }); 

如果您不能改變原有的組件集合,那麼你必須創建具有新的,過濾組件列表新RigActions。

1

這將找到RigActions匹配rigActionTypeID以及具有與給定componentTypeID

var actions = db.RigActions.Where(ra => ra.RigActionTypeID == rigActionTypeID 
       && ra.Components.Any(c => c.ComponentTypeID == componentTypeID)); 
+0

釘住它。儘管由於他的完整性,我最終將Olivier標記爲公認的答案。 – drewwyatt