C# LINQXML总是那么凌乱吗?

C# LINQXML总是那么凌乱吗?,c#,.net,linq,linq-to-xml,C#,.net,Linq,Linq To Xml,XML的结构如下所示: var subset = from item in document.Descendants("Id") where item.Value == itemId.ToString() select new PurchaseItem() { Id = int.Parse(item.Parent.Element("Id").Value), Name = ite

XML的结构如下所示:

var subset = from item in document.Descendants("Id")
             where item.Value == itemId.ToString()
             select new PurchaseItem() {
                 Id = int.Parse(item.Parent.Element("Id").Value),
                 Name = item.Parent.Element("Name").Value,
                 Description = item.Parent.Element("Description").Value,
                 Price = int.Parse(item.Parent.Element("Price").Value)
             };

Id和price都是整数值。名称和描述是字符串

我发现
linqtoxml
非常适合我使用它的目的,这只是一个片段。但是,另一方面,我觉得它应该或者可以更干净。在这个片段中,演员阵容似乎是最明显的问题

有什么建议吗?

我假设您也有一个“项目”节点

您可以这样做,假设您正在使用XElement.Load()加载文档


不是更好,但更容易阅读

实际上,IMO使用cast比调用
int.Parse
更好。以下是我将如何编写您的查询:

var subset = from item in document.Elements("Item")
             where item.Element("Id").Value == itemId.ToString()
             select new PurchaseItem() {
                 Id = int.Parse(item.Element("Id").Value),
                 Name = item.Element("Name").Value,
                 Description = item.Element("Description").Value,
                 Price = int.Parse(item.Element("Price").Value)
             };

在您的示例中,您可以通过查找
元素而不是
来稍微整理一下,以避免每次都得到
父项

string id = itemId.ToString(); // We don't need to convert it each time!

var subset = from item in document.Descendants("Id")
             where item.Value == id
             let parent = item.Parent
             select new PurchaseItem
             {
                 Id = (int) parent.Element("Id"),
                 Name = (string) parent.Element("Name"),
                 Description = (string) parent.Element("Description"),
                 Price = (int) parent.Element("Price")
             };

考虑为
PurchaseItem
编写一个新的构造函数,该构造函数接受XML元素,因此您可以编写:

var subset = from item in document.Descendants("Item")
             where item.Element("Id").Value == itemId.ToString()
             select new PurchaseItem()
                        {
                            Id = int.Parse(item.Element("Id").Value),
                            Name = item.Element("Name").Value,
                            Description = item.Element("Description").Value,
                            Price = int.Parse(item.Element("Price").Value)
                        };

约翰,你对为什么要这样做,而不是我表现出来的方式有什么评论吗?@Jon-怎么会呢。价值不是必需的?这是在幕后隐式调用的吗?XElement为常见数据类型定义了自定义强制转换操作符。因此,当您强制转换一个XElement时,实际上是在调用其中一个操作符,它读取值并转换它。您避免显式调用
.Value
,原因有两个:一是Value是字符串,而这些自定义运算符是在XElement上定义的,而不是字符串。第二,强制转换恰好为null的XElement将只返回null,而对null XElement调用.Value将导致异常。过滤时很有用。@Mitchel:我试图在搜索本身方面尽可能接近原始搜索,只是简化了它。我本来就有这个,但在玩了代码之后改变了它。所以+1告诉我这是可以做到的。尝试使用XmlReader,甚至是旧的XMLDOM来做到这一点,您将重新评估您对“凌乱”的看法。;)使用dynamic,这里的语法将更加清晰。想象一下
ID=item.ID
,等等@Noldorin-“untidy”更合适;)我过去在XMLReader上的工作,现在很混乱。如果你使用XSD,你可以使用Linq到XSD(在codeplex上)来生成一个很好的类型库是的,很公平。无论如何,我想你至少有你的答案。:)
var subset = from item in document.Descendants("Item")
             where item.Element("Id").Value == itemId.ToString()
             select new PurchaseItem()
                        {
                            Id = int.Parse(item.Element("Id").Value),
                            Name = item.Element("Name").Value,
                            Description = item.Element("Description").Value,
                            Price = int.Parse(item.Element("Price").Value)
                        };
select new PurchaseItem(item.Parent);