2012-04-03 24 views
6

Koşullu veri seçimi için bazı "LINQ" yolu var mı, yani ilk boşsa başka bir kaynaktan mı seçilsin? Bunun bir örneği, öğelerin bir ağaç yapısına sahip olmanız ve bir kökü ya da boşsa, o çocuklardan bir varlık almak istiyorsanız.LINQ içinde koşullu seçim (boşsa yerine seçin)

Ben şu örneği vardır: uzatma yöntemi

IEnumerable<Item> items = ...; 
// Item has a Assets property that returns IEnumerable<Asset> 
// Item has a SubItems property that returns IEnumerable<Item> 
// i.e. other items with assets in them 

// getting assets from a "main" item 
var assets = item.Assets.Where(a => HasRelevantAsset(a)); 

// if there were no relevant assets in the "main" item 
if (!assets.Any()) { 
    // then reselect from "subitems" assets instead 
    assets = item.SubItems.SelectMany(item => 
     item.Assets.Where(a => HasRelevantAsset(a))); 
} 

// HasRelevantAsset(Asset) is a static method that returns 
// true if it is the asset that is needed 
+0

Bunun için oldukça iyi bir kullanım gibi görünüyor? operatör - var varlıklar = bir şey mi ?? bir şey_else. Çalışmayacak, ama olsa hoş olurdu. – zmbq

cevap

1

LINQ yolu

var assets = item.Any(a=>HaRelevantAsset(a)) ? item.Where(a => HasRelevantAsset(a)) : 
        item.SubItems.SelectMany(item => 
          item.Assets.Where(a => HasRelevantAsset(a))); 
diğer varyantı tercih olacaktır

çirkin biraz bakacağız inanıyoruz

public static IEnumerable<Asset> SelectRelevantAssets(this Item item) 
{ 
    var assetsInItemFound = false; 
    foreach (var asset in item.Assets) 
    { 
     if (HasRelevantAsset(asset)) 
     { 
      assetsInItemFound = true; 
      yield return asset; 
     } 
    } 
    if (assetsInItemFound) 
    { 
     yield break; 
    } 
    else 
    { 
     foreach (var subItem in item.SubItems)   
      foreach (var asset in subItem.Assets) 
       if (HasRelevantAsset(asset)) 
        yield return asset; 
    } 
} 





İlk ben

if (!assetsInItemFound) 
     { 
      yield break; 
     } 
     else 
     { 
      foreach (var subItem in item.SubItems)   
       foreach (var asset in SelectRelevantAssets(subItem)) 
         yield return asset; 
     } 

gibi olacağını düşünüyorum, SelectRelevantAssets bir özyinelemeli çağrı denemek istedim Ama bu AltÖğe varlıklarının Öğeler koleksiyonunda bulunan varlıklarını içerecektir