实体框架添加了太多记录
本文关键字:太多 记录 添加 框架 实体 | 更新日期: 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);
}
}
}
为什么每次都需要插入新的上下文?方法UpdatePatients
和UpdateDrugs
都是私有的,你可以对所有链接的操作使用相同的上下文,我相信你不会得到重复的:
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