[英]LINQ to XML - where clause in Let statement
More troubles with LINQ. LINQ带来更多麻烦。 Just hoping that someone could please help.
只是希望有人可以帮忙。
Here's the structure I'm working with; 这是我正在使用的结构;
<root>
<Level1>
<Level2>
<Level3>
<Car>
<Price PaymentType="Cash">200</Price>
<Price PaymentType="Credit">500</Price>
</Car>
</Level3>
</Level2>
</Level1>
</root>
I'm trying to create two Let variables, that do this; 我正在尝试创建两个Let变量,它们可以完成此操作;
Let priceCash = ??? // should return 200
Let priceCredit = ??? // should return 500
To complicate things more, not all Cars have a Credit Price. 更复杂的是,并非所有汽车都有信用价格。 For these I'd like to return -1.
对于这些,我想返回-1。
Here's the butchered code I came up with; 这是我想到的代码。
// get all Price elements
let PriceList = CarList.Elements("Price")
// try to get the first Price element where PaymentType==Cash
let priceCash = PriceList.Where(c => PriceList.Attributes("PaymentType").First().Value == "Cash")
// try to get the first Price element where PaymentType==Credit
let priceCredit = PriceList.Where(c => PriceList.Attributes("PaymentType").First().Value == "Credit")
Is there a better way to do that? 有更好的方法吗? It seems to work, but then I run into trouble here;
看来可行,但是后来我在这里遇到了麻烦。
select new MyObj
{
Price1 = priceCash == null ? -1 : priceCash.ElementAt(0).Value,
Price2 = priceCredit == null ? -1 : priceCredit.ElementAt(0).Value,
}).ToList<MyObj>();
ElementAt(0) is causing an exception when the element isn't found. 找不到元素时,ElementAt(0)导致异常。
cheers 干杯
The following should be more robust: 以下内容应更可靠:
// try to get the first Price element where PaymentType==Cash
let priceCash = PriceList.FirstOrDefault(c => ((string)c.Attribute("PaymentType")) == "Cash")
// try to get the first Price element where PaymentType==Credit
let priceCredit = PriceList.FirstOrDefault(c => ((string)c.Attribute("PaymentType")) == "Credit")
select new MyObj
{
Price1 = priceCash == null ? -1 : (int)priceCash,
Price2 = priceCredit == null ? -1 : (int)priceCredit
}).ToList<MyObj>();
First of all, use Attribute
method, instead of Attributes().First
chain and (string)XAttribute
conversion instead of XAttribute.Value
property: 首先,使用
Attribute
方法而不是Attributes().First
链和(string)XAttribute
转换而不是XAttribute.Value
属性:
// get all Price elements
let PriceList = CarList.Elements("Price")
// try to get the first Price element where PaymentType==Cash
let priceCash = PriceList.Where(c => (string)c.Attribute("PaymentType") == "Cash")
// try to get the first Price element where PaymentType==Credit
let priceCredit = PriceList.Where(c => (string)c.Attribute("PaymentType") == "Credit")
And what even more important, use DefaultIfEmpty
to get -1
when elements are not present: 还有更重要的是,当元素不存在时,使用
DefaultIfEmpty
获得-1
:
select new MyObj
{
Price1 = priceCash.Select(x => (int)x).DefaultIfEmpty(-1).First(),
Price2 = priceCredit.Select(x => (int)x).DefaultIfEmpty(-1).First()
}).ToList<MyObj>();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.