使用DbSet查找和延迟加载将Entity Framework外键散布为空

时间:2018-07-04 15:05:13

标签: c# entity-framework-6

正如标题所述,我的代码中偶尔有空条目。我找不到任何模式,因为当代码一次运行而另一次失败时,下面的一个周期可以工作。

失败的代码:

var cycle = _dbContext.RenewalCycles.Find(businessSystemId, caseId, action, cycle);

var renewalDateEvent = cycle.CaseEvents?.FirstOrDefault(
   caseEvent => caseEvent.TPEvent.EventClassifications.Any(eventClassification => eventClassification.ClassificationId == Classifications.RenewalDueDate));

型号:

TPRenewalCycle:

public class TPRenewalCycle
{
    [Key, Column(Order = 0)]
    [ForeignKey("TPCase")]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    [MaxLength(15)]
    public string BusinessSystemId { get; set; }

    [Key, Column(Order = 1)]
    [ForeignKey("TPCase")]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int CaseId { get; set; }

    public virtual TPCase TPCase { get; set; }

    [Key, Column(Order = 2)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    [MaxLength(5)]
    public string Action { get; set; }

    [Key, Column(Order = 3)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Cycle { get; set; }

    public int? Year { get; set; }

    [MaxLength(50)]
    public string YearDescription { get; set; }

    public bool IsActive { get; set; }

    public bool IsCurrent { get; set; }

    public virtual ICollection<TPCaseEvent> CaseEvents { get; set; }

}

TPCaseEvent:

public class TPCaseEvent
{
    [Key, Column(Order = 0)]
    [ForeignKey("TPRenewalCycle")]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    [MaxLength(15)]
    public string BusinessSystemId { get; set; }

    [Key, Column(Order = 1)]
    [ForeignKey("TPRenewalCycle")]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int CaseId { get; set; }

    [Key, Column(Order = 2)]
    [ForeignKey("TPRenewalCycle")]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    [MaxLength(5)]
    public string Action { get; set; }

    [Key, Column(Order = 3)]
    [ForeignKey("TPRenewalCycle")]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Cycle { get; set; }

    public virtual TPRenewalCycle TPRenewalCycle { get; set; }

    [Key, Column(Order = 4)]
    [ForeignKey("TPEvent")]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int EventNo { get; set; }

    public virtual TPEvent TPEvent { get; set; }

    public DateTime? DueDate { get; set; }

    public DateTime? EventDate { get; set; }
}

TPEvent:

public class TPEvent
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int EventNo { get; set; }

    [MaxLength(100)]
    public string InternalName { get; set; }

    [MaxLength(100)]
    public string ExternalName { get; set; }

    [Column(TypeName = "nvarchar(MAX)")]
    [MaxLength]
    public string Description { get; set; }

    public virtual ICollection<TPEventClassification> EventClassifications { get; set; }
}

TPEventClassification:

public class TPEventClassification
{
    [Key, Column(Order = 0)]
    [ForeignKey("TPClassification")]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public Classifications ClassificationId { get; set; }

    public virtual TPClassification TPClassification { get; set; }

    [Key, Column(Order = 1)]
    [ForeignKey("TPEvent")]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int EventNo { get; set; }

    public virtual TPEvent TPEvent { get; set; }
}

TPClassification:

public class TPClassification
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public Classifications ClassificationId { get; set; }

    [MaxLength(100)]
    public string Description { get; set; }

    public bool IsCyclical { get; set; }

    [MaxLength(400)]
    public string Comment { get; set; }

    public virtual ICollection<TPEventClassification> EventClassifications { get; set; }
}

TPEvent为空

enter image description here

例外:

  

对象引用未设置为对象的实例。

第二次运行时,它是通过System.Data.Entity.DynamicProxies加载的。

enter image description here

为什么会在这里发生?我是否需要跳过Find,而将FirstOrDefaultInclude一起用于TPEvent?

1 个答案:

答案 0 :(得分:0)

在案例中也出现了相同的错误,因此我将展示如何修复该错误。像下面的FindFirstOrDefault都抛出了相同的异常。

//Sporadic exceptions like above. "Object reference not set to an instance of an object."
var tpCase = _DbContext.Cases
    .FirstOrDefault(x => x.BusinessSystemId == businessSystemId &&
                         x.CaseId == caseId);

但是,当我在查询中包括所有内容时,它就起作用了:

var tpCase = _DbContext.Cases
    .Where(x => x.BusinessSystemId == businessSystemId &&
                x.CaseId == caseId)
    .Include(tpCase => tpCase.RenewalCycles.Select(renewalCycle => renewalCycle.CaseEvents.Select(caseEvent => caseEvent.TPEvent.EventClassifications)))
    .FirstOrDefault();