2012-04-03 76 views
6

是否有一些「LINQ」方法可以有條件選擇數據,即如果第一個數據庫爲空,則從另一個數據源選擇?一個例子是如果你有一個項目的樹形結構,並且你想從一個根節點或者如果它是空的,從它的子節點獲得一些資源。LINQ中的條件選擇(如果爲空,請選擇)

我下面舉個例子:

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

這似乎是一個相當不錯的用途?運營商 - 'var assets =東西? something_else'。它不會工作,但如果它確實會很好。 – zmbq 2012-04-03 08:33:54

回答

1

相信LINQ的方式將看上去有點難看

var assets = item.Any(a=>HaRelevantAsset(a)) ? item.Where(a => HasRelevantAsset(a)) : 
        item.SubItems.SelectMany(item => 
          item.Assets.Where(a => HasRelevantAsset(a))); 

我會選擇其他的變型,擴展方法

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





首先我想嘗試SelectRelevantAssets遞歸調用,我想會是這樣

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

但是,這將包括在子項資產的項目集合中發現的資產