在Linq查询中构建'where'子句

时间:2009-05-25 13:50:16

标签: c# linq linq-to-xml dynamic-queries

在这个查询中,我总是想要'普通'类型元素 如果设置了_includeX标志,我也想要'workspace'类型元素 有没有办法把它写成一个查询?或者在提交查询之前根据_includeX构建where子句?

    if (_includeX) {
    query = from xElem in doc.Descendants(_xString)
        let typeAttributeValue = xElem.Attribute(_typeAttributeName).Value
        where typeAttributeValue == _sWorkspace ||
              typeAttributeValue == _sNormal
        select new xmlThing
        {
            _location = xElem.Attribute(_nameAttributeName).Value,
            _type = xElem.Attribute(_typeAttributeName).Value,
        }; 
}
else {
    query = from xElem in doc.Descendants(_xString)
        where xElem.Attribute(_typeAttributeName).Value == _sNormal
        select new xmlThing
        {
            _location = xElem.Attribute(_nameAttributeName).Value,
            _type = xElem.Attribute(_typeAttributeName).Value,
        }; 
}

1 个答案:

答案 0 :(得分:1)

您可以将其分解为单独的谓词:

Predicate<string> selector = x=> _includeX 
  ? x == _sWorkspace || x == _sNormal
  : x == _sNormal; 

query = from xElem in doc.Descendants(_xString)
      where selector(xElem.Attribute(_typeAttributeName).Value)
      select new xmlThing
      {
          _location = xElem.Attribute(_nameAttributeName).Value,
          _type = xElem.Attribute(_typeAttributeName).Value,
      };

或者内联条件:

query = from xElem in doc.Descendants(_xString)
    let typeAttributeValue = xElem.Attribute(_typeAttributeName).Value
    where (typeAttributeValue == _sWorkspace && _includeX) ||
          typeAttributeValue == _sNormal
    select new xmlThing
    {
        _location = xElem.Attribute(_nameAttributeName).Value,
        _type = xElem.Attribute(_typeAttributeName).Value,
    }; 

或者删除查询表达式用法并以这种方式执行: -

var all = doc.Descendants(_xString);
var query = all.Where( xElem=> {
      var typeAttributeValue = xElem.Attribute(_typeAttributeName).Value;
      return typeAttributeValue == _sWorkspace && includeX ) || typeAttributeValue == _sNormal;
})
.Select( xElem =>
    select new xmlThing
    {
        _location = xElem.Attribute(_nameAttributeName).Value,
        _type = xElem.Attribute(_typeAttributeName).Value,
    })

或者将第一个和第三个结合起来并执行:

Predicate<string> selector = x=> _includeX 
  ? x == _sWorkspace || x == _sNormal
  : x == _sNormal; 

query = doc.Descendants(_xString)
      .Where(xElem => selector(xElem.Attribute(_typeAttributeName).Value))
      .Select(xElem => new xmlThing
      {
          _location = xElem.Attribute(_nameAttributeName).Value,
          _type = xElem.Attribute(_typeAttributeName).Value,
      };)

这完全取决于在你的环境中最干净的工作。

帮自己一个忙,在深度中购买(并阅读!)C#,一点一点地学习这些东西都会更快有意义...