我有几个课程
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;
如何处理这些情况?我的班级应该重新设计吗?
答案 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#目前没有安全的导航操作符,但根据这个:
我们很快就会得到一个:&#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 }); }
}
}