首页 > 解决方案 > 当有零/空条目时,如何处理对一对多(或零)实体的迭代?

问题描述

我一直在NullReferenceException尝试迭代一行中的空条目。

public class Person
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public Address Address { get; set; }
        public int AddressID { get; set; }
    }

public class Address
    {
        public int ID { get; set; }
        public string FirstLine { get; set; }
        public string SecondLine { get; set; }
    }

使用默认的脚手架模板,_context.Person.Include(c => c.Address);

无论是否有地址,该视图都可以正常工作。

但是,我现在将默认索引页面替换为更新的网格,该网格通过 AJAX 加载,具有过滤和分页机制。为此,我需要将数据转换为我的 ViewModel

我希望能够将地址显示为文本。我尝试了以下方法:

        var tmp = _context.Person.Include(x => x.Address).ToList();

        tmp.ForEach(x => vm.List.Add(new IndexListItem()
        {
            Name = x.Name,
            Address = x.Address.FirstLine + " " + x.Address.SecondLine,
            ID = x.ID

        }));

但是,在调试时,Address 似乎总是为空,即使行上有数据。

我很确定我可以在标准的 foreach 循环中执行此操作,并进行 if null 检查,但是,我不禁觉得这是非常简单的事情,而且我把它复杂化了。

有没有更简单的方法来返回我需要的地址详细信息?

标签: c#linqentity-framework-core

解决方案


正如我在评论中所说,你应该在一个声明中做到这一点:

vm.List = _context.Person
    .Select(p => new IndexListItem
    {
        Name = p.Name,
        Address = p.Address.FirstLine + " " + p.Address.SecondLine,
        ID = p.ID
    }).ToList();

这有两个优点:

  1. 它被翻译成 SQL,因此只从数据库中提取了四个必填字段(这与更广泛的记录有很大的不同)。
  2. EF 将生成考虑空值的 SQL。

如果你不想要" "结果,你可以做......

Address = (p.Address.FirstLine + " " + p.Address.SecondLine).Trim()

...或者...

Address = p.Address.FirstLine != null ? p.Address.FirstLine + " " : "")
    + p.Address.SecondLine

但我认为查看数据并不重要。


推荐阅读