1

LINQ のさらなるトラブル。誰かが助けてくれることを願っています。

これが私が取り組んでいる構造です。

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

これを行う 2 つの 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) は、要素が見つからないときに例外を引き起こしています。

乾杯

4

2 に答える 2

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>();
于 2013-09-19T14:00:31.103 に答える
1

まず、チェーンAttributeの代わりにメソッドを使用し、プロパティの代わりに変換を使用します。Attributes().First(string)XAttributeXAttribute.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>();
于 2013-09-19T14:45:41.103 に答える