1

我不知道这个例外是什么。就在我以为我掌握了 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;
4

3 回答 3

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();
于 2012-05-29T18:25:55.750 回答
1

Because you are trying to cast the IEnumerable return type from your Linq to type PatientClass - the CLR can not do that since they are not related types.

You need to add some more Linq there to return a single instance of PatientClass.

于 2012-05-29T18:19:03.300 回答
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();
于 2012-05-29T18:19:24.833 回答