2012-04-03 129 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; 
     } 

但是,这将包括在子项资产的项目集合中发现的资产