2013-08-28 64 views
0

對象模型給出以下DTO的定義:家長/孩子的XML DTO與LINQ

[Serializable] 
internal class OrderCollection : List<Order> 
{ } 

[Serializable] 
internal class Order 
{ 
    public string OrderId { get; set; } 
    public OrderDetailCollection OrderDetails { get; set; } 
} 


[Serializable] 
internal class OrderDetailCollection : List<OrderDetail> 
{ } 

[Serializable] 
internal class OrderDetail 
{ 
    internal OrderDetail() 
    { 
    } 

    /*public string ParentOrderId { get; set; }*/ 
    public string ItemName { get; set; } 
    public int Quantity { get; set; } 
} 

和下面的XML:

<root> 
    <orders> 

     <order orderId="ABC123"> 
      <orderDetails> 

       <orderDetail itemName="Bike" quantity="1"/> 
       <orderDetail itemName="TeddyBear" quantity="2"/> 
       <orderDetail itemName="Doll" quantity="3"/> 

      </orderDetails> 
     </order> 
     <!-- --> 
     <order orderId="DEF234"> 
      <orderDetails> 

       <orderDetail itemName="Truck" quantity="4"/> 
       <orderDetail itemName="Marbles" quantity="5"/> 
       <orderDetail itemName="BoardGame" quantity="6"/> 

      </orderDetails> 
     </order> 

    </orders> 
</root> 

有沒有一種方法來填充整個對象模型(導致在OrderCollection類型的一個對象中使用Linq .....和在「一次通過」中?

這裏是我所擁有的........(我可以獲得「Order(s)」填充) ......但不知道如何得到孩子們?還是我必須拿2分接受它然後「匹配它們」?

XDocument xDoc = XDocument.Load(fullFileName); 

    //XNamespace ns = XNamespace.Get("http://schemas.microsoft.com/developer/msbuild/2003"); 
    string ns = string.Empty; 

    List<Order> lineItems = new List<Order> 
    (
      from list in xDoc.Descendants(ns + "orders") 
      from item in list.Elements(ns + "order") 
      where item != null 
      select new Order 
      { 
       OrderId = item.Attribute("orderId") == null ? string.Empty : item.Attribute("orderId").Value 
      } 
     ); 


    OrderCollection returnCollection = new OrderCollection(); 
       returnCollection.AddRange(lineItems); 
+1

關於XML的結構 - 我認爲你可以將'orderDetail'元素直接放在'order'元素的下面;然後你可以使用'item.Elements(「orderDetail」)'只提取'orderDetail'元素。另外,除了'orders'元素外的'root'元素還有別的東西,你可以使用'orders'作爲根元素。 –

+0

好的。其一,這是我必須解析的XML的一個虛擬的例子。二,我無法控制輸入xml。但謝謝你的建議。 – granadaCoder

回答

1

試試這個:

internal class OrderDetailCollection : List<OrderDetail> 
{ 
    internal OrderDetailCollection() {} 
    internal OrderDetailCollection(IEnumerable<OrderDetail> src) 
    { 
     AddRange(src); 
    } 
} 

List<Order> lineItems = new List<Order> 
(
    from list in xDoc.Descendants(ns + "orders") 
    from item in list.Elements(ns + "order") 
    where item != null 
    select new Order 
    { 
     //note that the cast is simpler to write than the null check in your code 
     //http://msdn.microsoft.com/en-us/library/bb387049.aspx 
     OrderId = (string)item.Attribute("orderId"), 
     OrderDetails = new OrderDetailCollection(
      from detail in item.Descendants("orderDetail") 
      select new OrderDetail { 
       ItemName = (string)detail.Attribute("itemName"), 
       Quantity = (int)detail.Attribute("quantity") 
      } 
     ) 
    } 
); 

如果您不需要單獨的類的集合,並且可以使用List<Order>List<OrderDetails>代替,那麼你可以這樣做:

List<Order> lineItems = new List<Order> 
(
    from list in xDoc.Descendants(ns + "orders") 
    from item in list.Elements(ns + "order") 
    where item != null 
    select new Order 
    { 
     OrderId = (string)item.Attribute("orderId"), 
     OrderDetails = (
      from detail in item.Descendants("orderDetail") 
      select new OrderDetail { 
       ItemName = (string)detail.Attribute("itemName"), 
       Quantity = (int)detail.Attribute("quantity") 
      } 
     ).ToList() 
    } 
); 
+0

從item.Elements(「orderDetail」)....詳細的item.Elements(「orderDetails」)中使用.. ..的細節(對於另外的spot-on響應)..... (「orderDetail」)謝謝! – granadaCoder

+1

@granadaCoder固定使用'.Descendants'而不是'.Elements'。 –