直接从linq查询返回一个类

本文关键字:一个 返回 linq 查询 | 更新日期: 2023-09-27 17:57:32

我还是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返回一个null异常。我理解这是因为linq查询返回了一个空类。

所以我的问题是,在不运行foreach循环并手动添加所有内容的情况下,是否可以直接将内容添加到查询中的类中并返回?(如下所示:)

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

如果这是个愚蠢的问题,我很抱歉。

感谢

直接从linq查询返回一个类

您需要区分读取项目序列和读取单个项目。目前,ReadPerson中的person变量的类型实际上是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方法在这里对您很有用。

根据我的阅读方式,您只需要:

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")
            });
}

此地址:

  • 返回多个后代的问题
  • 未指定firstname/lastname的问题

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

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

以下行存在无效的强制转换问题。你应该让编译器来帮助你(参见我修改的函数)。

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;
}