如何在Linq where子句中引用has-many-through关系?

时间:2014-02-28 17:53:09

标签: c# sql linq

我有课程:

  • COMPONENTTYPE
    • ID
    • 名称
    • ...
  • 组件
    • 编号
    • ComponentTypeID
    • ...
  • RigAction
    • ID
    • RigActionTypeID(指向下面的RigActionType)
    • ComponentID(指向上面的组件)
  • RigActionType
    • 名称
    • ...

我正在尝试使用RigActionsRigActionTypeID查询所有ComponentTypeID,并且正在努力使用Linq的where()方法。我在下面的代码中找到了第一部分,但是在检查第二部分中的componentTypeID属性时遇到了问题。

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

2 个答案:

答案 0 :(得分:1)

这将找到RigActions匹配rigActionTypeID且至少有一个component与给定的componentTypeID

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

答案 1 :(得分:1)

SelectMany使枚举枚举变得平坦。如果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<>不是只读的):< / p>

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

如果列表是readonly,请执行以下操作:

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

如果您不允许更改原始组件集合,则必须创建具有新的过滤组件列表的新RigActions。