Xml Thowing奇怪的异常

时间:2012-05-29 18:15:52

标签: linq-to-xml

我不知道这个例外是什么。正当我以为我得到了linq这样的事情。我得到了这个例外:

Unable to cast object of type 'WhereSelectEnumerableIterator`2[System.Xml.Linq.XElement,TestImplementationIdeas.PatientClass]' to type 'TestImplementationIdeas.PatientClass'.

现在,我知道为什么会抛出这个异常。

PatientClass template = (PatientClass)(from templates in xDocument.Descendants("template").Where
                                                       (templates => ((templates.Descendants("element").Attributes("name").ToString() == "EncounterId") && templates.Descendants("element").Attributes("value").ToString() == Enc.ToString())) //elem.XPathSelectElements(string.Format("//templates/template[./elements/element[@name=\"PopulationPatientID\"and @value='{0}' and @enc='{1}']]",PopulationPatID, Enc))
                                                       select new PatientClass
                                                       {
                                                           PatientId = Convert.ToInt32("0" + templates.XPathSelectElement("elements/element[@name='PatientId']").Attribute("value").Value),
                                                           EMPIID = Convert.ToInt32("0" + templates.XPathSelectElement("elements/element[@name='EMPIID']").Attribute("value").Value),
                                                           //public int PopulationPatientID { get; set; }
                                                           FirstName = templates.XPathSelectElement("elements/element[@name='FirstName']").Attribute("value").Value,
                                                           LastName = templates.XPathSelectElement("elements/element[@name='LastName']").Attribute("value").Value,

                                                       });
            return template != null ? template : null;

3 个答案:

答案 0 :(得分:1)

因为你试图从你的Linq转换IEnumerable返回类型到类型PatientClass - CLR不能这样做,因为它们不是相关的类型。

您需要在那里添加更多Linq以返回PatientClass的单​​个实例。

答案 1 :(得分:1)

您的LINQ查询返回IEnumerable<PatientClass>,您尝试将其转换为单个PatientClass。如果您真的只想从查询中返回一个对象,请在其上调用.First()

PatientClass template = (from templates in xDocument.Descendants("template").Where
                                                   (templates => ((templates.Descendants("element").Attributes("name").ToString() == "EncounterId") && templates.Descendants("element").Attributes("value").ToString() == Enc.ToString())) //elem.XPathSelectElements(string.Format("//templates/template[./elements/element[@name=\"PopulationPatientID\"and @value='{0}' and @enc='{1}']]",PopulationPatID, Enc))
                                                   select new PatientClass
                                                   {
                                                       PatientId = Convert.ToInt32("0" + templates.XPathSelectElement("elements/element[@name='PatientId']").Attribute("value").Value),
                                                       EMPIID = Convert.ToInt32("0" + templates.XPathSelectElement("elements/element[@name='EMPIID']").Attribute("value").Value),
                                                       //public int PopulationPatientID { get; set; }
                                                       FirstName = templates.XPathSelectElement("elements/element[@name='FirstName']").Attribute("value").Value,
                                                       LastName = templates.XPathSelectElement("elements/element[@name='LastName']").Attribute("value").Value,

                                                   }).First();

答案 2 :(得分:1)

通常,LINQ查询始终返回IEnumerable<>对象,在您的情况下为IEnumerable<PatientClass>。您需要执行其他操作以将集合过滤到单个对象。

//  will return the first `PatientClass` in the collection.  
//   And will throw an exception if the collection is empty.
return template.First(); 

//  will return the first `PatientClass` in the collection or return the default value       
//   (null in this case) if the collection is empty.
return template.FirstOrDefault(); 

// will return the only `PatientClass` in the collection if the collection only has 
//  one object and will throw an exception if it is empty or has more than 1 object.
return template.Single(); 

// will return the only `PatientClass` in the collection if the collection only has 
//  one object, the default value (null in this case) if it is empty and will throw an    
//  exception if it has more than 1 object.
return template.SingleOrDefault(); 

而不是OrDefault()方法,如果要控制空值时返回的值,则有DefaultIfEmpty<>()扩展方法,如果集合为空,则可以指定值。

// will return the first element in the collection, but if it is empty, 
//  it will return a new Patient class object created with the default constructor instead of a null
return template.DefaultIfEmpty(new PatientClass()).First();