将实体投影到匿名对象,而其某些导航属性可能为空

Projecting an entity to an anonymous object while some of its navigation properties might be null

我希望这个问题不会令人困惑,我想做的是将匿名对象列表绑定到网格,我有一个 class Client,我的项目是客户端放入匿名对象列表中,以便我可以在网格中显示其详细信息,如下所示:

this.gridControl1.DataSource = _clients.Select(c => new
{
    c.ClientId,
    c.FirstName,
    c.LastName,
    c.Details.Country, //throws NullReferenceException since I added a 
                       //client with no details.
    c.Details.City,
    c.Details.Adress,
    c.Details.Email
}).OrderByDescending(c => c.ClientId);

问题是有些客户可能还没有添加详细信息..尝试绑定时我显然得到了 NullReferenceException.. 我做投影的原因是为了避免在网格中有一个无用的列 Details

所以,有什么解决办法吗?或遇到这种情况的不同方法?谢谢

假设字段是字符串,试试

country = c.Details != null ? c.Details.Country : "", // or null or another
                                                      // appropriate default value

等而不是

c.Details.Country

您可以使用三元运算符来执行此操作:

c.Details == null ? null : c.Details.Country

没有看到客户端是如何创建的,我无法确定什么对您有用。以下是一些建议:

  1. 使用 "blank" 详细信息对象实例化客户端,该对象在所有属性中都具有 string.Empty。

  2. 将 Client.Details 设为私有 属性,然后公开 public 属性(国家/地区、城市等),其中只有 getter 而 return当私有 Details 对象为 null 时为空字符串。如果您需要从外部访问 Details 对象,请使用方法而不是 属性:

    class Details
    {
        public string Country { get; set; }
    }
    class Client
    {
        private Details _details;
        public string Country
        {
            get
            {
                return _details == null ? string.Empty : _details.Country;
            }
        }
        public Details GetDetails()
        {
            return _details;
        }
    }
    

这会有额外的好处,允许您消除匿名选择,因为 Details 对象将不再是 属性,因此会被绑定过程忽略。您可以将客户集合直接绑定到网格。