【发布时间】:2014-09-25 15:59:30
【问题描述】:
在玩弄代码并检查示例后,我在为嵌套类获取正确查询时遇到问题,我最终得到了以下内容。
基本的 XML 是
<Connections>
<Connection>
<ConnectionName>CConnect</ConnectionName>
<SiteA SiteName="Site1" IP="000">Site1info</SiteA>
<SiteB SiteName="Site2" IP="000">Site2info</SiteB>
</Connection>
</Connections>
输出到列表的 LINQ 查询
List<ConnectionItem> NewConnectionList = xDoc.Root.Elements("Connection")
.Select(q => new ConnectionItem
{
ID = (string)q.Element("ID"),
ConnectionName = (string)q.Element("ConnectionName"),
TypeList = (string)q.Element("TypeList"),
SiteA = (SiteDetails)q.Elements("SiteA").Select(s => new SiteDetails { SiteName = (string)q.Attribute("SiteName"), Router = (string)q.Attribute("Router"), IP = (string)q.Attribute("IP") }),
SiteB = (SiteDetails)q.Elements("SiteB").Select(s => new SiteDetails { SiteName = (string)q.Attribute("SiteName"), Router = (string)q.Attribute("Router"), IP = (string)q.Attribute("IP") })
}).ToList();
SiteA 和 SiteB 似乎是问题所在,它是 ConnectionItem 类中的子类调用 SiteDetails。编译器显示查询没有问题,但是在运行时我发现了转换为 SiteDetails 的错误。
System.InvalidCastException:无法将“WhereSelectEnumerableIterator`2[System.Xml.Linq.XElement,Piccolo_Test.SiteDetails]”类型的对象转换为“Piccolo_Test.SiteDetails”类型。
在 c:\Visual Studio 2013\Projects\Test\Test\Forms\frmMain.cs:line 493 中的 Piccolo_Test.frmMain.b__c(XElement q) 处
在 System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
在 System.Collections.Generic.List
1..ctor(IEnumerable1 集合)在 System.Linq.Enumerable.ToList[TSource](IEnumerable`1 源)
在 c:\Visual Studio 2013\Projects\Test\Test\Forms\frmMain.cs:line 492 中的 Piccolo_Test.frmMain.readXML() 处
这是 lambda 表达式的问题还是我错误地转换了子类?
【问题讨论】:
-
Select返回集合,如果你想要一个对象,请使用First或FirstOrDefault或Single或SingleOrDefault代替 -
Elements("SiteA").Select(..)返回一个IEnumerable<SiteDetails>。改为Elements("SiteA").Select(..).FirstOrDefault() -
考虑到您在获取属性值时引用了
q,您可能会遇到SiteA和SiteB完全为空的问题。q是Connection元素,没有属性。