LINQ to XML - Let语句中的where子句

时间:2013-09-19 13:52:48

标签: c# linq-to-xml

LINQ更麻烦。只是希望有人可以请求帮助。

这是我正在使用的结构;

<root>
   <Level1>
     <Level2>
       <Level3>
         <Car>
           <Price PaymentType="Cash">200</Price>
           <Price PaymentType="Credit">500</Price>
         </Car>
       </Level3>
     </Level2>
   </Level1>
</root>

我正在尝试创建两个Let变量,这样做;

Let priceCash = ??? // should return 200
Let priceCredit = ??? // should return 500

为了使事情复杂化,并非所有汽车都有信用价格。对于这些我想返回-1。

这是我提出的屠宰代码;

// 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")

有没有更好的方法呢?它似乎有效,但后来我遇到了麻烦;

select new MyObj
{
    Price1 = priceCash == null ? -1 : priceCash.ElementAt(0).Value,
    Price2 = priceCredit == null ? -1 : priceCredit.ElementAt(0).Value,
}).ToList<MyObj>();

ElementAt(0)在找不到元素时导致异常。

欢呼声

2 个答案:

答案 0 :(得分:1)

以下内容应该更加强大:

// 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>();

答案 1 :(得分:1)

首先,使用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")

更重要的是,当元素不存在时,使用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>();