Linq选择查询,如何将结果追加到类的对象

时间:2016-02-22 01:05:44

标签: c# linq linq-to-sql

在下面截取的c#代码中,我不是每次都创建新的tradeContributions,而是需要添加到此IEnumerable集合。

我以为我可以执行tradeContributions.add(),但add()方法不可用。



public static IEnumerable<TradeContribution> GetTradeContributions(uint portfolioId, List<uint> portfolioIdList, IEnumerable<DateTime> nodeDateList, int? whatIfBatchNumber = null)
        {

            // THIS IS THE ORIGINAL CODE
            IEnumerable<TradeContribution> tradeContributions = new List<TradeContribution> { };


tradeContributions = (from tc in xml.XPathSelectElement("body/portfolios/portfolio/contributions").Elements("tradeContribution")
	  select new TradeContribution
	  {
		  SysId = tc.Attribute("sysId") == null ? 0 : int.Parse(tc.Attribute("sysId").Value),
		  TradeContextId = tc.Attribute("contextId") == null ? 0 : int.Parse(tc.Attribute("contextId").Value),
		  TradeId = tc.Attribute("tradeId") == null ? "" : tc.Attribute("tradeId").Value,
		  ProductType = tc.Attribute("desc").Value,
		  ProductDescription = tc.Attribute("desc").Value, // TODO: In future could lookup the description in a reference data cache
		  Contribution = decimal.Parse(tc.Attribute("contribution").Value)
	  })
	  .OrderByDescending(x => x.Contribution);



    // ... code omitted for brevity

    // THIS IS MY NEW CODE TO HANDLE THE NEW REQUIREMENTS
    foreach (XElement pfElem in xml.XPathSelectElements("body/portfolios/portfolio"))
    {
        tradeContributions = (from tc in pfElem.XPathSelectElement("contributions").Elements("tradeContribution")
    	  select new TradeContribution
    	  {
    		  SysId = tc.Attribute("sysId") == null ? 0 : int.Parse(tc.Attribute("sysId").Value),
    		  TradeContextId = tc.Attribute("contextId") == null ? 0 : int.Parse(tc.Attribute("contextId").Value),
    		  TradeId = tc.Attribute("tradeId") == null ? "" : tc.Attribute("tradeId").Value,
    		  ProductType = tc.Attribute("desc").Value,
    		  ProductDescription = tc.Attribute("desc").Value,
    		  Contribution = decimal.Parse(tc.Attribute("contribution").Value)
    	  }
        );
    }
 
          return tradeContributions;
        }
    }
&#13;
&#13;
&#13;

如何将每个新的tradeContribution添加到我的收藏中?

2 个答案:

答案 0 :(得分:3)

我在这里有一个问题:

IEnumerable<TradeContribution> tradeContributions = new List<TradeContribution> { };

这是一个局部变量......那么我们为什么要将它锁定为有限合约,IEnumerable?它实际上是List<T>,所以只需声明它:

var  tradeContributions = new List<TradeContribution> { };

完成后,您需要做的就是将foreach中的代码块更改为:

tradeContributions.AddRange((from tc in pfElem.XPathSelectElement("contributions").Elements("tradeContribution")
  select new TradeContribution
  {
      SysId = tc.Attribute("sysId") == null ? 0 : int.Parse(tc.Attribute("sysId").Value),
      TradeContextId = tc.Attribute("contextId") == null ? 0 : int.Parse(tc.Attribute("contextId").Value),
      TradeId = tc.Attribute("tradeId") == null ? "" : tc.Attribute("tradeId").Value,
      ProductType = tc.Attribute("desc").Value,
      ProductDescription = tc.Attribute("desc").Value,
      Contribution = decimal.Parse(tc.Attribute("contribution").Value)
  }));

基本上,恕我直言,通过使用IEnumerable,你创造了一个人为的限制,如果有一些逻辑边界被交叉可能是有意义的。但是没有......所以你不应该这样做。

<强>更新

好的,既然我看到了整个方法的代码,我就能理解(有点)为什么要做IEnumerable声明。我认为变量是多余的。你只需要将Concat()两个LINQ放在一起并返回结果,恕我直言。

有点像这样:

public static IEnumerable<TradeContribution> GetTradeContributions(uint portfolioId, List<uint> portfolioIdList, IEnumerable<DateTime> nodeDateList, int? whatIfBatchNumber = null)
{
    var originalItems = (from tc in xml.XPathSelectElement("body/portfolios/portfolio/contributions").Elements("tradeContribution")
    select new TradeContribution
    {
      SysId = tc.Attribute("sysId") == null ? 0 : int.Parse(tc.Attribute("sysId").Value),
      TradeContextId = tc.Attribute("contextId") == null ? 0 : int.Parse(tc.Attribute("contextId").Value),
      TradeId = tc.Attribute("tradeId") == null ? "" : tc.Attribute("tradeId").Value,
      ProductType = tc.Attribute("desc").Value,
      ProductDescription = tc.Attribute("desc").Value, // TODO: In future could lookup the description in a reference data cache
      Contribution = decimal.Parse(tc.Attribute("contribution").Value)
  })
  .OrderByDescending(x => x.Contribution);



// ... code omitted for brevity

// THIS IS MY NEW CODE TO HANDLE THE NEW REQUIREMENTS
    var additionalItems = xml.XPathSelectElements("body/portfolios/portfolio")
        .SelectMany(pfElem => 
        {
            (from tc in pfElem.XPathSelectElement("contributions").Elements("tradeContribution")
          select new TradeContribution
          {
          SysId = tc.Attribute("sysId") == null ? 0 : int.Parse(tc.Attribute("sysId").Value),
          TradeContextId = tc.Attribute("contextId") == null ? 0 : int.Parse(tc.Attribute("contextId").Value),
          TradeId = tc.Attribute("tradeId") == null ? "" : tc.Attribute("tradeId").Value,
          ProductType = tc.Attribute("desc").Value,
          ProductDescription = tc.Attribute("desc").Value,
          Contribution = decimal.Parse(tc.Attribute("contribution").Value)
          }
        });

    return originalItems.Concat(additionalItems);
}

答案 1 :(得分:1)

由于您已经按新IEnumerable

创建了List
IEnumerable<TradeContribution> tradeContributions = new List<TradeContribution> { };

为什么不完全将其声明为List以简化您的问题?

List<TradeContribution> tradeContributions = new List<TradeContribution> { };

然后,您可以借助AddRange中已有的Add(以及List)方法使用此方法:

foreach (XElement pfElem in xml.XPathSelectElements("body/portfolios/portfolio"))
{
    var temp = (from tc in pfElem.XPathSelectElement("contributions").Elements("tradeContribution")
      select new TradeContribution
      {
          SysId = tc.Attribute("sysId") == null ? 0 : int.Parse(tc.Attribute("sysId").Value),
          TradeContextId = tc.Attribute("contextId") == null ? 0 : int.Parse(tc.Attribute("contextId").Value),
          TradeId = tc.Attribute("tradeId") == null ? "" : tc.Attribute("tradeId").Value,
          ProductType = tc.Attribute("desc").Value,
          ProductDescription = tc.Attribute("desc").Value,
          Contribution = decimal.Parse(tc.Attribute("contribution").Value)
      }
    );
    tradeContributions.AddRange(temp.ToArray()); //then add the results to the List
}

否则,如果您希望将查询添加到IEnumerable,那么您也可以使用Concat

foreach (XElement pfElem in xml.XPathSelectElements("body/portfolios/portfolio"))
{
    var temp = (from tc in pfElem.XPathSelectElement("contributions").Elements("tradeContribution")
      select new TradeContribution
      {
          SysId = tc.Attribute("sysId") == null ? 0 : int.Parse(tc.Attribute("sysId").Value),
          TradeContextId = tc.Attribute("contextId") == null ? 0 : int.Parse(tc.Attribute("contextId").Value),
          TradeId = tc.Attribute("tradeId") == null ? "" : tc.Attribute("tradeId").Value,
          ProductType = tc.Attribute("desc").Value,
          ProductDescription = tc.Attribute("desc").Value,
          Contribution = decimal.Parse(tc.Attribute("contribution").Value)
      }
    );
    tradeContributions = tradeContributions.Concat(temp);
}