2013-08-28 63 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'。 –