tags:

views:

278

answers:

1

In this query, I always want the 'normal' type element.
If the _includeX flag is set, I want the 'workspace' type elements, too.
Is there a way to write this as one query? Or build the where clause based on _includeX before submitting the query?

TIA...

    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,
        }; 
}
A: 

You can break it into a separate predicate:

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,
      };

Or inline the condition:

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,
    };

Or remove query expression usage and do it this way:-

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,
    })

Or combine the first and third and do:

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,
      };)

It all depends what's going to work cleanest in your context.

Do yourself a favour and buy (and read!) C# in Depth and it'll all make sense a lot more quickly that learning this stuff bit by bit...

Ruben Bartelink