2013-02-07 32 views
0

我有一个列表:var_assets_root有一个嵌套的子列表:contents。我可以在根列表上加入一个连接,并通过在var_assets_root中对索引项目进行两次连接,从其他两个列表lst_invtypes_assetslst_stations_composite_retribution中的额外项目扩充它。但我也想要加入子目录var_assets_root-->contents\b.contents内的项目,下面的代码目前还没有做到。 Image>>structure of var_assets_root in watch windowc#linq加入列表中的子列表

mysql mysql_object = new mysql(); 
    List<mysql.invtypes_asset> lst_invtypes_assets = mysql_object.dbmysql_invtypes_asset_to_list(); 
    List<mysql.stations_composite_retribution> lst_stations_composite_retribution = mysql_object.dbmysql_select_stastations_composite_retribution_to_list(); 
    var lst_assets_list = new AssetList("134399", "343434SxSFX7qO81LqUCberhS1OQtktMvARFGED0ZRSN5c4XP230SA", "434367527"); 
    lst_assets_list.Query(); 
    var var_assets_root = lst_assets_list.assets.ToList(); 

    var var_assets_root_typeid_station 
    = from b in var_assets_root 
    join c in lst_invtypes_assets on b.typeID equals c.typeID 
    join d in lst_stations_composite_retribution on b.locationID equals d.stationID 
    select new {b.contents, b.flag, b.itemID, b.locationID, d.solarSystemName, d.security, d.securityClass, d.regionName, b.quantity, b.singleton, b.typeID, c.groupID, c.marketGroupID, c.volume, 
     c.typeName, c.description}; 

我已经做了运行LINQ查询每一个内容分名单,并相应地分配价值的解决方案。

private void btn_evenet_Click(object sender, EventArgs e) 
{ 
    Stopwatch stopwatch1 = new Stopwatch(); 
    Stopwatch stopwatch2 = new Stopwatch(); 
    stopwatch1.Start(); 
    mysql mysql_object = new mysql(); 
    List<mysql.invtypes_asset> lst_invtypes_assets = mysql_object.dbmysql_invtypes_asset_to_list(); 
    List<mysql.stations_composite_retribution> lst_stations_composite_retribution = mysql_object.dbmysql_select_stastations_composite_retribution_to_list(); 
    AssetList lst_assets_list = new AssetList("2312099", "J&VNM14RFUkSxSFX7qAAAAAA1OQtktMvYTVZZBhkO23235c4Z&HJKODPQLM", "123231527"); 
    lst_assets_list.Query(); 
    var var_assets_root = lst_assets_list.assets.ToList(); 
    var var_assets_root_typeid_station 
    = from b in var_assets_root 
    join c in lst_invtypes_assets on b.typeID equals c.typeID 
    join d in lst_stations_composite_retribution on b.locationID equals d.stationID 
     select new { b.contents, b.flag, b.itemID, b.locationID, d.solarSystemName, d.security, d.securityClass, d.regionName, b.quantity, b.singleton, b.typeID, c.groupID, c.marketGroupID, c.volume, 
     c.typeName, c.description}; 
    var lst_assets_root_typeid_station = var_assets_root_typeid_station.ToList(); // Using .ToArray() is about 200ms faster than .ToList() 
    stopwatch2.Start(); 
    for (Int32 a = 0; a < lst_assets_root_typeid_station.Count(); a++) 
    { 
    if (lst_assets_root_typeid_station[a].contents.Count() >= 0) 
    { 
     for (Int32 b = 0; b < lst_assets_root_typeid_station[a].contents.Count(); b++) 
     { 
     var var_row_invtypes_assets = lst_invtypes_assets.Where(x => x.typeID == lst_assets_root_typeid_station[a].contents[b].typeID).ToArray(); 
     lst_assets_root_typeid_station[a].contents[b].groupID = var_row_invtypes_assets[0].groupID; 
     lst_assets_root_typeid_station[a].contents[b].typeName = var_row_invtypes_assets[0].typeName; 
     lst_assets_root_typeid_station[a].contents[b].description = var_row_invtypes_assets[0].description; 
     lst_assets_root_typeid_station[a].contents[b].volume = var_row_invtypes_assets[0].volume; 
     lst_assets_root_typeid_station[a].contents[b].marketGroupID = var_row_invtypes_assets[0].marketGroupID; 
     if (lst_assets_root_typeid_station[a].contents[b].contents.Count() != 0) 
     { 
      for (Int32 c = 0; c < lst_assets_root_typeid_station[a].contents[b].contents.Count(); c++) 
      { 
      var_row_invtypes_assets = lst_invtypes_assets.Where(x => x.typeID == lst_assets_root_typeid_station[a].contents[b].contents[c].typeID).ToArray(); 
      lst_assets_root_typeid_station[a].contents[b].contents[c].groupID = var_row_invtypes_assets[0].groupID; 
      lst_assets_root_typeid_station[a].contents[b].contents[c].typeName = var_row_invtypes_assets[0].typeName; 
      lst_assets_root_typeid_station[a].contents[b].contents[c].description = var_row_invtypes_assets[0].description; 
      lst_assets_root_typeid_station[a].contents[b].contents[c].volume = var_row_invtypes_assets[0].volume; 
      lst_assets_root_typeid_station[a].contents[b].contents[c].marketGroupID = var_row_invtypes_assets[0].marketGroupID; 
      } 
     } 
     }   
    } 
    } 
    stopwatch2.Stop(); 
    stopwatch1.Stop(); 
    lbl_stopwatch1.Text = "Everything: " + stopwatch1.Elapsed.ToString("mm\\:ss\\.ff"); // 1.53 seconds no debugging 
    lbl_stopwatch2.Text = "contents sublists: " + stopwatch2.Elapsed.ToString("mm\\:ss\\.ff"); // contents sublists take 1.03 seconds no debugging 
} 
} 

一旦我说“屈服”啪啪从内容节点一叠一个内容节点时getAllContents叫我适应我的代码和功能,因此现在所有的内容节点得到递归到并有自己的空值填充从linq查询。此外,linq创建var_assets_root_typeid_station之后的新代码现在几乎快了两倍。谢谢。

private void btn_evenet_Click(object sender, EventArgs e) 
{ 
    Stopwatch stopwatch1 = new Stopwatch(); 
    Stopwatch stopwatch2 = new Stopwatch(); 
    stopwatch1.Start(); 
    mysql mysql_object = new mysql(); 
    List<mysql.invtypes_asset> lst_invtypes_assets = mysql_object.dbmysql_invtypes_asset_to_list(); 
    List<mysql.stations_composite_retribution> lst_stations_composite_retribution = mysql_object.dbmysql_select_stastations_composite_retribution_to_list(); 
    AssetList lst_assets_list = new AssetList("12345678", "ABCDEFFGHIKLkokJDSD213123", "12345678"); 
    lst_assets_list.Query(); 
    var var_assets_root = lst_assets_list.assets.ToList(); 
    var var_assets_root_typeid_station 
    = from b in var_assets_root 
    join c in lst_invtypes_assets on b.typeID equals c.typeID 
    join d in lst_stations_composite_retribution on b.locationID equals d.stationID 
     select new 
     {b.contents, b.flag, b.itemID, b.locationID, d.solarSystemName, d.security, d.securityClass, d.regionName, b.quantity, b.singleton, b.typeID, c.groupID, c.marketGroupID, c.volume, 
     c.typeName, c.description}; 
    var lst_assets_root_typeid_station = var_assets_root_typeid_station.ToList(); // Using .ToArray() is about 200ms faster than .ToList() 
    stopwatch2.Start(); 
for (Int32 a = 0; a < lst_assets_root_typeid_station.Count(); a++) 
    { 
    if (lst_assets_root_typeid_station[a].contents.Count() > 0) 
    { 
     for (Int32 z = 0; z < lst_assets_root_typeid_station[a].contents.Count(); z++) 
     { 
     foreach (AssetList.Item contentnode in getAllContents(lst_assets_root_typeid_station[a].contents[z])) 
     { 
      var var_row_invtypes_assets = lst_invtypes_assets.Where(x => x.typeID == contentnode.typeID).ToArray(); 
      contentnode.groupID = var_row_invtypes_assets[0].groupID; 
      contentnode.typeName = var_row_invtypes_assets[0].typeName; 
      contentnode.description = var_row_invtypes_assets[0].description; 
      contentnode.volume = var_row_invtypes_assets[0].volume; 
      contentnode.marketGroupID = var_row_invtypes_assets[0].marketGroupID; 
     } 
     } 
    } 
    }  
    stopwatch2.Stop(); 
    stopwatch1.Stop(); 
    lbl_stopwatch1.Text = "Everything: " + stopwatch1.Elapsed.ToString("mm\\:ss\\.ff"); // 1.16 seconds no debugging 
    lbl_stopwatch2.Text = "contents sublists: " + stopwatch2.Elapsed.ToString("mm\\:ss\\.ff"); // contents sublists take 0.63 seconds no debugging 
} 

IEnumerable<AssetList.Item> getAllContents(AssetList.Item contentNode) 
{ 
    if (contentNode.contents.Count == 0) 
    { 
    yield return contentNode; 
    } 
    else 
    { 
    foreach (AssetList.Item subContentNode in contentNode.contents) 
    { 
     yield return subContentNode; 
     foreach (AssetList.Item subSubContentNode in getAllContents(subContentNode)) 
     yield return subSubContentNode; 
    } 
    } 
} 
+6

你真的应该尽力与标准的命名约定相一致。它会让你的代码更容易阅读。 – Servy

+0

@Servy也许海报的代码符合特定组的标准命名约定。但是,我同意在张贴到SO之前进行一些编辑可能很有用。 – maxwellb

+0

我是一个业余爱好者新手编码器。我用自己的直觉来命名。将来我会尝试采用标准的命名约定 – xav2075

回答

1

难道你不是在寻找SelectMany吗?

var contents = lst_invtypes_assets.contents.SelectMany(x => x.contents);

+0

如何在linq查询中使用.SelectMany()var var_assets_root_typeid_station = ...所以我可以在内容子列表上做一个连接。 – xav2075

0

我认为你在说的是,你要访问的外部.contents属性,如果它包含任何contents,然后访问这些,太,等等...递归。

尽管可以通过定义递归Func<AssetList.Item, IEnumerable<AssetList.Item>>和一行LINQ使用.Aggregate来实现,但定义自己的递归方法可能会更容易/更易读。

IEnumerable<AssetList.Item> getAllContents(AssetList.Item station) { 
    foreach (AssetList.Item subStation in station.contents) { 
     yield return subStation; 
     foreach (AssetList.Item subSubStation in getAllContents(substation)) 
      yield return subSubStation; 
    } 
} 

然后,您可以做一个简单的foreach(var station in getAllContents(parentStation))或修改这包括原站,使之成为扩展方法,等等