2012-08-02 69 views
0

我是linq的新手,並且在編寫查詢時會遇到麻煩,這些查詢會返回我正在查找的數據。 XML文件有訂單,每個訂單都有采購訂單信息和產品,每個訂單都有自己的元素和後代。我需要將所有的訂單及其後代查詢爲一個集合,但由於某種原因,linq查詢語法對我來說是非常直觀的。在構建正確的linq-to-xml查詢時遇到困難

這裏是我的xml的截斷樣本

<fulfillment> 
    <orders> 
     <order> 
     <isbulk>true</isbulk> 
     <purchaseorder> 
      <id>Acme Inustries</id> 
      <quantity>15</quantity> 
     </purchaseorder> 
     <items> 
      <item> 
       <prods> 
        <prod> 
        <seq>1</seq> 
        <issuetype>NEW</issuetype> 
        <loop> 
         <proxy>xyz123</proxy> 
         <servicecode>55</servicecode> 
        </loop> 
        </prod> 
        <prod> 
        <seq>2</seq> 
        <issuetype>NEW</issuetype> 
        <loop> 
         <proxy>abc987</proxy> 
         <servicecode>121</servicecode> 
        </loop> 
        </prod> 
       </prods> 
      </item> 
     </items> 
     </order> 
     <order> 
     <isbulk>true</isbulk> 
     <purchaseorder> 
      <id>ABC Co</id> 
      <quantity>10</quantity> 
     </purchaseorder> 
     <items> 
      <item> 
       <prods> 
        <prod> 
        <seq>1</seq> 
        <issuetype>NEW</issuetype> 
        <loop> 
         <proxy>xyz456</proxy> 
         <servicecode>998</servicecode> 
        </loop> 
        </prod> 
        <prod> 
        <seq>2</seq> 
        <issuetype>NEW</issuetype> 
        <loop> 
         <proxy>abc654</proxy> 
         <servicecode>664</servicecode> 
        </loop> 
        </prod> 
       </prods> 
      </item> 
     </items> 
     </order> 
    </orders> 
</fulfillment> 

我的物體看起來有點像這樣:

public class order 
{ 
    public bool IsBulk { get; set; } 

    public PurchaseOrder PurchaseOrder = new PurchaseOrder(); 
    public List<prod> ListOfProds = new List<prod>(); 
} 

public class prod 
{ 
    public string Seq { get; set; } 
    public string IssueType { get; set; } 

    public string Proxy { get; set; } 
    public string ServiceCode { get; set; } 
} 

public class PurchaseOrder 
{ 
    public string ID { get; set; } 
    public string Quantity { get; set; } 
} 

所以我一直工作在查詢了一天中最好的部分和只是似乎無法做到。下面是我到目前爲止有:

List<order> orderlist = new List<order>(); 
XDocument xmlDoc = XDocument.Load(FilePath); 

var list = (from myOrder in xmlDoc.Descendants("order")    
select new  
{ 
    linq_orderIsBulk = Convert.ToBoolean(myOrder.Element("isbulk").Value), 

    linq_purchaseOrderID = myOrder.Element("purchaseorder").Element("id").Value, 
    linq_purchaseOrderQuantity = myOrder.Element("purchaseorder").Element("quantity").Value, 

    prodlist = myOrder.Element("items").Element("item").Element("prods").Elements("prod").Select(e => new 
    {     
     Linq_seq = e.Element("seq").Value, 
     Linq_IssueType = e.Element("issuetype").Value, 

     Linq_proxy = e.Element("loop").Element("proxy").Value, 
     Linq_serviceCode = e.Element("loop").Element("servicecode").Value 
    }).ToList() 
}); 

//做代碼把收集到列表清單orderlist

但是當我這樣做,我似乎最終得到一個「未將對象引用設置爲一個對象的實例。「子查詢出錯。當我註釋掉Linq_proxy和Linq_serviceCode行時,我得到的結果不是正確的。當我遍歷列表並獲取單個訂單時,請查看該訂單的產品列表,計數是該文件(4)的prod的總數量,而不是該訂單的2。有什麼想法嗎?

+0

我想你想'xmlDoc.Elements(「order」)'。 – jrummell 2012-08-02 16:50:39

+0

是的,對不起。這是「循環」。編輯 – Jeremy 2012-08-02 16:59:33

+0

jrummell,我試過了,現在list.Count()= 0 – Jeremy 2012-08-02 17:00:07

回答

3

我只是跑這一點,它工作正常:

var orders = new List<order>(
    from myOrder in xmlDoc.Descendants("order") 
    let purchaseOrder = myOrder.Element("purchaseorder") 
    select new order { 
     IsBulk = Convert.ToBoolean(myOrder.Element("isbulk").Value), 
     PurchaseOrder = new PurchaseOrder { 
      ID = purchaseOrder.Element("id").Value, 
      Quantity = purchaseOrder.Element("quantity").Value 
     }, 
     ListOfProds = new List<prod>(
      from product in myOrder.Descendants("prod") 
      let loop = product.Element("loop") 
      select new prod 
      {     
       Seq = product.Element("seq").Value, 
       IssueType = product.Element("issuetype").Value, 
       Proxy = loop.Element("proxy").Value, 
       ServiceCode = loop.Element("servicecode").Value 
      } 
     ) 
    } 
); 

注意,您可以直接投影集合到你的類型的對象,所以你不必有代碼以後創建訂單採集。

+0

不知道爲什麼舊的沒有工作,但我從來沒有得到好的結果。但是,無論如何,您的新查詢都很棒。很棒。謝謝。 – Jeremy 2012-08-03 13:36:23

+0

有什麼方法可以添加行號錯誤檢查嗎?所以如果數據不好,它會返回導致問題的行號(或最後一行)?我認爲我可以通過在集合中添加linenumber屬性來強制我的方式,但這看起來不是一個好方法。 – Jeremy 2012-08-03 14:35:21

+0

不幸的是沒有。這將是一個很大的幫助,不是嗎?但是我已經看到,如果你使用步調試器並且「步入」LINQ的執行,你通常可以看到正在得到異常的查詢部分。 – Jacob 2012-08-03 14:38:10