2010-01-06 60 views
0

我正在學習LINQ,這看起來像一個相當簡單的問題。我有一個半工作解決方案,但我相信它可以被清理。使用join和GroupBy()將LINQ轉換爲XML。它是否正確?

propertyAuto節點代表一輛id = 606的汽車。 該節點需要至少有兩個child propertyValue節點,一個引用屬性爲「Book」和一個「Auto」的vehicleValuation元素。 (我的代碼沒有檢查這個,他們可能都是自動或現在預訂)

最後,我需要獲取同一輛車的賬面價值和自動價值。

請注意,我永遠不會知道任何ID或idRef的事前和將來會有多輛車。

這是我現在的代碼(可以複製到LINQPad!)

var data = XElement.Parse (@" 
<MyXML> 
    <propertyAuto id='606'> 
    <Values> 
     <propertyValue idRef='f95d5dce-8152-4e9e-889e-7433d32664d6' /> 
     <propertyValue idRef='cd1a83a7-dd04-41f9-b31c-5408a38ac777' /> 
    </Values> 
    </propertyAuto> 
    <Valuations> 
    <vehicleValuation id='cd1a83a7-dd04-41f9-b31c-5408a38ac777' 
    valuationType='Auto' estimatedValue='8350.00' /> 
    <vehicleValuation id='f95d5dce-8152-4e9e-889e-7433d32664d6' 
    valuationType='Book' estimatedValue='12475.00' /> 
    </Valuations> 
</MyXML>"); 

var valuations = from property in data.Descendants("propertyValue") 
       join value in data.Descendants("vehicleValuation") 
       on 
        (string)property.Attribute("idRef") 
       equals 
        (string)value.Attribute("id") 
       where property.Parent.Descendants("propertyValue").Count() > 1 
       && ((string)value.Attribute("valuationType") == "Auto" || (string)value.Attribute("valuationType") == "Book")    
       select new { Value = value.Attribute("estimatedValue").Value, Type = value.Attribute("valuationType").Value, PropertyID = property.Parent.Parent.Attribute("id").Value }; 

valuations.Dump(); 

var values = valuations.GroupBy(x=> x.PropertyID).FirstOrDefault(); 
string auto = values.Where(x => x.Type == "Auto").Select(x=>x.Value).First().ToString(); 
string book = values.Where(x => x.Type == "Book").Select(x=>x.Value).First().ToString(); 

auto.Dump(); 
book.Dump(); 

這是可行的,或者我應該搬到XPath的,等等?

回答

1

很明顯,您的解決方案是可行的,因爲它的工作原理!我還要把它遠一點得到的結果作爲汽車用屬性的列表,你可以很容易地檢查:

var carProperties = from propertyAuto in data.Descendants("propertyAuto") 
        select new 
        { 
         Id = propertyAuto.Attributes("id").First().Value, 
         Properties = from property in propertyAuto.Descendants("propertyValue") 
            join value in data.Descendants("vehicleValuation") 
            on property.Attribute("idRef").Value 
            equals value.Attribute("id").Value 
            select new 
            { 
             Value = value.Attribute("estimatedValue").Value, 
             Type = value.Attribute("valuationType").Value, 
             PropertyID = property.Parent.Parent.Attribute("id").Value 
            } 
        }; 

var cars = from car in carProperties 
      select new 
      { 
       Id = car.Id, 
       Auto = car.Properties.Where(x => x.Type == "Auto").Select(x => x.Value).First(), 
       Book = car.Properties.Where(x => x.Type == "Book").Select(x => x.Value).First() 
      }; 

注意,的GroupBy不再需要。

1
var valuations = el.Element("Valuations").Elements("vehicleValuation"); 
var carNodes = el.Elements("propertyAuto"); 
var cars = carNodes.Select(x => 
       new { 
        id = x.Attribute("id").Value, 
        PropertyValues = x.Element("Values").Elements("propertyValue"). 
             SelectMany(
               y => valuations.Where( 
                 val => val.Attribute("id").Value == y.Attribute("idRef").Value 
                    ).Select(valuation => 
                      new { 
                       Type = valuation.Attribute("valuationType"), 
                       EstVal = valuation.Attribute("estimatedValue") 
                       } 
                      ) 
               ) 
        }); 

有點複雜,但是這會創建一個匿名類型,其汽車ID與Property Values匹配。

如果您想直接使用Auto和Book值,可以這樣做。

var cars = carNodes.Select(car => 
       new { 
        id = car.Attribute("id").Value, 
        Auto = car.Element("Values").Elements("propertyValue"). 
             SelectMany(
               y => valuations.Where( 
                 val => val.Attribute("id").Value == y.Attribute("idRef").Value && 
                   val.Attribute("valuationType").Value == "Auto" 
                    ) 
                   .Select(valuation => valuation.Attribute("estimatedValue")) 
               ).SingleOrDefault(), 
        Book = car.Element("Values").Elements("propertyValue"). 
              SelectMany(
                y => valuations.Where(
                  val => val.Attribute("id").Value == y.Attribute("idRef").Value && 
                   val.Attribute("valuationType").Value == "Book" 
                     ) 
                    .Select(valuation => valuation.Attribute("estimatedValue")) 
               ).SingleOrDefault(), 
        });