直接从linq查询返回一个类

时间:2011-05-25 07:23:14

标签: c# linq c#-3.0 linq-to-xml

我还是LINQ的新手。是否可以执行以下操作:

例如,我有一个班级:

public class Person
{
        public string FirstName { get; set; }
        public string LastName { get; set; }
}

现在我想通过读取xml文件的内容并将其返回来将其作为类对象返回。

所以,如果我读到这个 xml文件:

<person>
    <firstname></firstname>
    <lastname></lastname>
</person>

阅读人(说这属于人类):

public static Person ReadPerson(xmlpath)
{
    XDocument xd = XDocument.Load(xmlpath);
    var person = (from p in xd.Descendants("person")
                  select new Person
                  {
                      FirstName = p.Element("firstname").value,
                      LastName = p.Element("lastname").value
                  });
    return person as Person;
}

现在如果我在其他地方做以下事情:

Person p = new Person();
p = People.Person(xmlpath);
Response.Write(p.FirstName);

这里,p.FirstName返回一个空异常。我理解的是因为linq查询返回了一个空类。

所以我的问题是,无论如何直接在查询中的类中添加内容并将其返回 没有运行foreach循环并手动添加所有内容 ? (如下所示:)

Person p = new Person();
foreach (var x in person)
{
    p.FirstName = x.FirstName;
    p.LastName = x.LastName;
}

对不起,如果这是一个愚蠢的问题。

由于

4 个答案:

答案 0 :(得分:4)

您需要区分读取项目的序列和阅读单个项目。目前person中的ReadPerson变量实际上属于IEnumerable<Person>类型 - 您将返回person as Person,它将为null,因为该序列实际上不是 Person的实例。如果您使用了强制转换而不是as,那么您之前已经看过了 - 但是您必须对类型进行任何这一事实应该警告您不是我做得很对。

我怀疑你真的想要这个:

public static IEnumerable<Person> ReadPeople(xmlpath)
{
    XDocument xd = XDocument.Load(xmlpath);
    return from p in xd.Descendants("person")
           select new Person
           {
               FirstName = p.Element("firstname").value,
               LastName = p.Element("lastname").value
           });
}

或者这个:

public static Person ReadPerson(xmlpath)
{
    XDocument xd = XDocument.Load(xmlpath);
    XElement element = xd.Descendants("person").First();
    return new Person
           {
               FirstName = element.Element("firstname").value,
               LastName = element.Element("lastname").value
           });
}

如果没有 person元素或多个个人元素,您还应该考虑要发生什么。 FirstFirstOrDefaultSingleSingleOrDefault方法对您有用。

答案 1 :(得分:2)

从我的阅读方式来看,您所需要的只是:

public static IEnumerable<Person> ReadPeople(xmlpath)
{
    XDocument xd = XDocument.Load(xmlpath);
    return (from p in xd.Descendants("person")
            select new Person
            {
                FirstName = (string)p.Element("firstname"),
                LastName = (string)p.Element("lastname")
            });
}

这解决了:

  • 返回多个后代
  • 的问题
  • 未指定名字/姓氏的问题

如果您打算只有一个,请使用Single() / First() / SingleOrDefault() / FirstOrDefault()

答案 2 :(得分:0)

我看到了问题! ReadPerson方法中的person不是Person类的实例,但集合(IEnumerable<Person>)和强制转换为Person会返回null

答案 3 :(得分:0)

以下行有无效的转换问题。您应该让编译器帮助您(请参阅我修改过的函数)。

return person as Person;

您应该返回一个人员列表而不是一个人。如果您确定xml中只有一个人,则可以调用Single()而不是ToList()。

public static List<Person> ReadPerson(xmlpath)
{
    XDocument xd = XDocument.Load(xmlpath);
    /*var person = (from p in xd.Descendants("person")
                  select new Person
                  {
                      FirstName = p.Element("firstname").value,
                      LastName = p.Element("lastname").value
                  });*/
    List<Person> persons = (from p in xd.Descendants("person")
                  select new Person
                  {
                      FirstName = p.Element("firstname").value,
                      LastName = p.Element("lastname").value
                  }).ToList();
    return persons;
}