Linq select 查询,如何将结果附加到 class 的 object
Linq select query, how to append results to object of a class
在下面截取的 c#
代码中,我不需要每次都创建一个新的 tradeContributions
,而是需要添加到此 IEnumerable
collection.
我以为我可以执行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;
}
}
如何将每个新的 tradeContribution
添加到我的 collection?
因为您已经通过新 List
创建了 IEnumerable
IEnumerable<TradeContribution> tradeContributions = new List<TradeContribution> { };
为什么不将其完全声明为 List
以简化您的问题?
List<TradeContribution> tradeContributions = new List<TradeContribution> { };
然后你可以在List
:
中已经可用的AddRange
(和Add
)方法的帮助下像这样使用它
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);
}
我对这里的这一行有疑问:
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 放在一起,然后 return 结果,恕我直言。
有点像这样:
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);
}
在下面截取的 c#
代码中,我不需要每次都创建一个新的 tradeContributions
,而是需要添加到此 IEnumerable
collection.
我以为我可以执行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;
}
}
如何将每个新的 tradeContribution
添加到我的 collection?
因为您已经通过新 List
IEnumerable
IEnumerable<TradeContribution> tradeContributions = new List<TradeContribution> { };
为什么不将其完全声明为 List
以简化您的问题?
List<TradeContribution> tradeContributions = new List<TradeContribution> { };
然后你可以在List
:
AddRange
(和Add
)方法的帮助下像这样使用它
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);
}
我对这里的这一行有疑问:
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 放在一起,然后 return 结果,恕我直言。
有点像这样:
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);
}