处理类中的null子对象?

时间:2014-05-08 14:32:30

标签: c# linq entity-framework class-design

我有几个课程

public class Person
{
   public int Id{get;set;}
   public string Name{get;set;}
   public virtual Institution Institution{get; set;}    
}
public class Institution
{
    public int Id{get;set;}
    public string Name{get;set;}
    public virtual InstitutionType InstitutionType { get; set; }

}
public class InstitutionType
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool Active { get; set; }
    public virtual ICollection<Institution> Institutions { get; set; }

}

此类是代码优先模型,它使用Entity Framework从数据库中的表中提取记录。通常情况下,机构表中没有InstitutionType。

当我使用以下代码并且记录没有InstitutionType数据时,我得到一个Null Reference Exception。

cm.InstitutionTypeId = person.Institution.InstitutionType == null ? 0 : contact.Institution.InstitutionType.Id;

如何处理这些情况?我的班级应该重新设计吗?

2 个答案:

答案 0 :(得分:1)

一般来说,你必须问自己:如果数据不存在,你将无法做什么,而你想做什么呢?

在您的示例中,如果person为null,您将无法执行任何操作。实际上,如果person为null,则可能永远不会输入您的代码,因此这是抛出ArgumentNullException或类似内容的好地方。

如果person.Institution为空,您将无法对机构执行任何操作。你必须跳过所有与机构有关的代码,但你可能会或可能不想抛出异常。可能不是。

如果缺少person.Institution.InstitutionType,您无法执行与机构类型有关的任何操作,但您可能会想出默认值。您可能希望将null InstitutionType视为具有ID = 0的InstitutionType,Name = String.Empty和Active = false。

答案 1 :(得分:1)

(编辑显示延迟加载代码示例)

目前,在使用可能为null的对象的属性之前,没有办法检查空引用。

cm.InstitutionTypeId = (person.Insitituion != null && person.Institution.InstitutionType != null) ? contact.Institution.InstitutionType.Id : 0;

C#目前没有安全的导航操作符,但根据这个:

http://blogs.msdn.com/b/jerrynixon/archive/2014/02/26/at-last-c-is-getting-sometimes-called-the-safe-navigation-operator.aspx

我们很快就会得到一个:&#34;?。&#34;

或者,您可以让您的Institution属性延迟加载新的Institution实例,该实例已使用ID为0的InstitutionType进行初始化。根据您在使用这些对象时所需的业务逻辑,这可能是也可能不是最佳方法。由于这些是实体对象,因此您需要确保了解创建新实例的数据含义,而不是设置对现有默认机构或InstitutionType的引用。希望这会有所帮助。

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }

    private Institution _Institution;
    public Institution Institution
    {
        get { return _Institution ?? (_Institution = new Institution()); }
    }

}
public class Institution
{
    public int Id { get; set; }
    public string Name { get; set; }

    private InstitutionType _InstitutionType;
    public InstitutionType InstitutionType
    {
        get { return _InstitutionType ?? (_InstitutionType = new InstitutionType() { Id = 0 }); }
    }

}