实体框架添加了太多记录

本文关键字:太多 记录 添加 框架 实体 | 更新日期: 2023-09-27 18:20:53

EDIT:有关工作代码,请参阅此问题的底部

我有两个表,病人和药物,我正在用数据源更新。我得到了一个当前的患者列表,然后根据需要迭代、更新或插入记录。这是毫无问题的。

当我反复查看该患者当前的药物时,问题就来了。我最终得到了原来病人的多份复印件。药物记录按预期转移(记录本身不会更改,因此插入新记录,忽略现有记录)。我最终得到了原始患者记录(从下面的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);
        }
    }
}

实体框架添加了太多记录

为什么每次都需要插入新的上下文?方法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