2013-07-02 89 views
0

编辑:请参阅此问题的底部的工作代码。实体框架添加太多记录

我有两张表,患者和药物,我正在更新数据馈送。我得到最新的患者列表,然后根据需要迭代并更新或插入记录。这工作没有问题。

当我迭代患者当前的药物时,麻烦来了。我最终得到了原始病人的多个副本。药物记录按预期转移(记录本身不会改变,因此插入新记录并忽略现有记录)。我最终得到原始患者记录(从下面的UpdatePatients()插入),然后为每个药物记录添加一个额外的患者记录。每个药物记录最后都有一个独特的PatientId。

类定义:

public class Patient 
{ 
    public int PatientId { get; set; } 

    [Required] 
    public int FacilityNumber { get; set; } 

    [Required] 
    public int PatNo { get; set; } 

    [Required] 
    public string Name { get; set; } 

    [Required] 
    public int Age { get; set; } 

    [Required] 
    public string Gender { get; set; } 

    [Required] 
    public DateTime VentStart { get; set; } 

    [Required] 
    public DateTime VentEnd { get; set; } 

    [Required] 
    public DateTime AdmitDate { get; set; } 

    public DateTime? DischargeDate { get; set; } 
} 

public class Drug 
{ 
    public int DrugId { get; set; } 

    [Required] 
    public int DrugDDI { get; set; } 

    [Required] 
    public int OrderId { get; set; } 

    [Required] 
    public string DrugName { get; set; } 

    [Required] 
    public DateTime DispenseDate { get; set; } 

    [Required] 
    public double UnitsDispensed { get; set; } 

    [ForeignKey("Patient")] 
    public int PatientId { get; set; } 
    public virtual Patient Patient { get; set; } 
} 

违规代码:

private static void UpdatePatients() 
{ 
    var Patients = DB2Patient.GetPatients(); 

    foreach (Patient p in Patients) 
    { 
     using (var PatientContext = new VAEContext()) 
     { 
      var ExistingPatientRecord = PatientContext.Patients.FirstOrDefault(
       ep => ep.PatNo == p.PatNo 
      ); 
      if (ExistingPatientRecord != null) 
      { 
       ExistingPatientRecord.VentEnd = p.VentEnd; 
       ExistingPatientRecord.DischargeDate = p.DischargeDate; 
       PatientContext.SaveChanges(); 
      } 
      else 
      { 
       PatientContext.Patients.Add(p); 
       PatientContext.SaveChanges(); 
      } 
     } 
     UpdateDrugs(p); 
    } 
} 

private static void UpdateDrugs(Patient p) 
{ 
    var Drugs = DB2Drug.GetDrugs(p.PatNo); 
    foreach (Drug d in Drugs) 
    { 
     using (var DrugContext = new VAEContext()) 
     { 
      var ExistingDrugRecord = DrugContext.Drugs.FirstOrDefault(
       ed => ed.DrugDDI == d.DrugDDI && 
         ed.DispenseDate == d.DispenseDate && 
         ed.OrderId == d.OrderId 
      ); 
      if (ExistingDrugRecord == null) 
      { 
       d.Patient = p; 
       DrugContext.Drugs.Add(d); 
       DrugContext.SaveChanges(); 
      } 
     } 
    } 
} 

编辑:工作代码:

private static void UpdatePatients() 
{ 
    var Patients = DB2Patient.GetPatients(); 

    using (var db = new VAEContext()) 
    { 
     foreach (Patient p in Patients) 
     { 
      var ExistingPatientRecord = db.Patients.FirstOrDefault(
       ep => ep.PatNo == p.PatNo 
      ); 
      if (ExistingPatientRecord != null) 
      { 
       ExistingPatientRecord.VentEnd = p.VentEnd; 
       ExistingPatientRecord.DischargeDate = p.DischargeDate; 
      } 
      else 
      { 
       db.Patients.Add(p); 
      } 
      UpdateDrugs(p, db); 
     } 
     db.SaveChanges(); 
    } 
} 

private static void UpdateDrugs(Patient p, VAEContext ctx) 
{ 
    var Drugs = DB2Drug.GetDrugs(p.PatNo); 
    foreach (Drug d in Drugs) 
    { 
     var ExistingDrugRecord = ctx.Drugs.FirstOrDefault(
      ed => ed.DrugDDI == d.DrugDDI && 
        ed.DispenseDate == d.DispenseDate && 
        ed.OrderId == d.OrderId 
     ); 
     if (ExistingDrugRecord == null) 
     { 
      d.Patient = p; 
      ctx.Drugs.Add(d); 
     } 
    } 
} 

回答

1

为什么新的上下文中插入每次有需要时间?这两种方法UpdatePatientsUpdateDrugs是私有的,你可以使用相同的上下文为所有链接的操作,我相信你不会得到重复的:

private static void UpdateDrugs(Patient p, VAEContext context) 

...

也有可能是没有必要为了节省每种药物,这样做可能会降低性能,并且在数据完整性方面做得不多。考虑每次链接更新保存上下文更改(例如在UpdatePatients中调用UpdateDrugs后)

除此之外,您可以查看ObjectContext.Attach及相关方法,了解如何将Patient对象与新创建的Drugs上下文实例

http://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.attach.aspx

+0

我仍然在学习EF和与之相关的最佳实践。这正是我所需要的,我还没有做到这一点。我会更新我的问题以包含未来参考的工作代码。谢谢! –