0

细节

我有 2 个表(Procedures、Surgeons)和一个查找表(ProcSurg)来创建多对多关系。

scar_Requests       scar_Procedures        scar_ProcSurg            scar_Surgeons
-------------       ---------------        -------------            -------------
RequestID      <>   ProcedureID       <>   ProcedureID(fk)   <>     SurgeonID
...                 RequestID              SurgeonID(fk)            ...
                    ...

一个请求可以有多个程序,每个程序可以有多个外科医生。

一切都正确保存,直到我有 2 个共享同一外科医生的程序。

Error: InvalidOperationException was unhandled
The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects.

我分离出保存这部分记录的代码以尝试隔离我的问题..

Addprocedures 是一个包含 1 个程序和外科医生列表的类

class Procedure
{
    public scar_Procedures Procedure { get; set; }
    public List<scar_Surgeons> Surgeons { get; set; }

    public void RemoveSurgeon(int SurgeonID)
    {
        Surgeons.Remove(Surgeons.Where(x => x.SurgeonID == SurgeonID).FirstOrDefault());
    }

    public Procedure()
    {
        Surgeons = new List<scar_Surgeons>();
    }
}

保存代码:使用 DBContext

    private void SaveProcSurg()
    {
        using (MCASURGContext db2 = new MCASURGContext())
        {
            foreach (Procedure p in AddProcedures)
            {
                if (p.Procedure.RequestID == 0)
                {
                    p.Procedure.RequestID = ReqID;
                }

                p.Procedure.scar_Surgeons.Clear();

                foreach (scar_Surgeons s in p.Surgeons)
                {
                    if (db2.ChangeTracker.Entries<scar_Surgeons>().Where(x => x.Entity.SurgeonID == s.SurgeonID).FirstOrDefault() == null)
                    {
                        db2.scar_Surgeons.Attach(s);
                    }
                    p.Procedure.scar_Surgeons.Add(s);
                }

                if (p.Procedure.ProcedureID == 0)
                {
                    db2.scar_Procedures.Add(p.Procedure);
                    db2.Entry(p.Procedure).State = System.Data.Entity.EntityState.Added;
                }
                else
                {
                    db2.scar_Procedures.Attach(p.Procedure);
                    db2.Entry(p.Procedure).State = System.Data.Entity.EntityState.Modified;
                }
            }
            db2.SaveChanges();
        }
        
    }

我尝试了几种不同的保存记录的方法,这是我最接近正确的方法。

我觉得这与我将外科医生连接到实体然后连接到程序的方式有关。任何关于我在哪里可以找到答案的帮助、想法或建议都会很棒!

一个多星期以来,我一直在无休止地搜索谷歌,我一直在努力思考 Entity Framework 到底在做什么,但我对此还是很陌生。

于 2013 年 9 月 24 日编辑

抱歉,这是评论部分的完整代码片段,其中包含 req 变量

 //Internal variable
 private scar_Requests req;
 private List<Procedure> AddProcedures = new List<Procedure>();

 //Gets a scar_Request from the DB
    private void GetRequest()
    {
        using (MCASURGContext db = new MCASURGContext())
        {
            req = db.scar_Requests.Include("scar_Procedures.scar_Surgeons").Include("scar_Status").Include("scar_Users.scar_Service").Where(x => x.RequestID == ReqID).FirstOrDefault();

            foreach (scar_Procedures p in req.scar_Procedures) { AddProcedures.Add(new Procedure() { Proc = p, Surgeons = p.scar_Surgeons.ToList() }); }
        }
}
4

1 回答 1

0

保持良好的形式,我会发布我的答案,因为我想我已经弄清楚了。也许它会在未来帮助某人。

我完全重写了保存并删除了很多我之前使用的无用代码,并且减少了对数据库的调用。还有其他我没有在上面发布的方法,它们保存了我浓缩成一个方法的记录的其他部分。

基本上,我从数据库中获取记录及其连接表,并遍历所有需要更新的字段/连接表并将其保存回数据库。(现在看起来非常明显,但我以前尝试过这种方式,我一定有什么问题,因为我第一次尝试这种方式时它不起作用。)

我不知道它是 100% 正确还是符合正常的编码标准,在它完全完成之前我还有一些最后的调整要做。

    private void SaveProcSurg()
    {
        using (MCASURGContext db2 = new MCASURGContext())
        {

            //Get Record from DB
            scar_Requests sReq = db2.scar_Requests.Include("scar_Users").Include("scar_Status").Include("scar_Procedures.scar_Surgeons").Where(x => x.RequestID == ReqID).FirstOrDefault();

            //Update Record fields
            sReq.CreationDate = req.CreationDate == null ? DateTime.Now : req.CreationDate = req.CreationDate;
            sReq.DateOfSurgery = dtpDateOfSurgery.Value;
            sReq.IsDeleted = false;
            sReq.IsScheduled = false;
            sReq.LatexAllergy = cbLatexAllergy.Checked;
            sReq.ModifiedDate = DateTime.Now;
            sReq.MRN = txtMRN.Text;
            sReq.PatientName = txtPatientName.Text;
            foreach (RadioButton rb in gbPatientType.Controls) if (rb.Checked == true) sReq.PatientType = rb.Text;
            sReq.PreOpDiagnosis = txtPreOpDiag.Text;
            sReq.PrimarySurgeon = txtPrimarySurgeon.Text;
            sReq.PrivateComment = txtPrivateComment.Text;
            sReq.PublicComment = txtPublicComment.Text;
            sReq.RequestID = ReqID;
            sReq.StatusID = req.StatusID;
            sReq.UserID = req.UserID;

            //Update Users/Status
            sReq.scar_Users = db2.scar_Users.Where(x => x.UserID == sReq.UserID).FirstOrDefault();
            sReq.scar_Status = db2.scar_Status.Where(x => x.StatusID == req.StatusID).FirstOrDefault();


            //Attach to DBContext
            db2.scar_Requests.Attach(sReq);


            //Update Procedures
            foreach (Procedure p in AddProcedures)
            {
                scar_Procedures pro = sReq.scar_Procedures.Where(x => x.ProcedureID == p.Proc.ProcedureID && p.Proc.ProcedureID != 0).FirstOrDefault();
                if (pro != null)
                {
                    pro.EnRecovery = p.Proc.EnRecovery;
                    pro.IsPrimary = p.Proc.IsPrimary;
                    pro.Laterality = p.Proc.Laterality;
                    pro.OrthoFastTrack = p.Proc.OrthoFastTrack;
                    pro.ProcedureID = p.Proc.ProcedureID;
                    pro.ProcedureText = p.Proc.ProcedureText;
                    pro.RequestID = ReqID;
                    pro.Site = p.Proc.Site;
                }
                else
                {
                    pro = new scar_Procedures();
                    pro.EnRecovery = p.Proc.EnRecovery;
                    pro.IsPrimary = p.Proc.IsPrimary;
                    pro.Laterality = p.Proc.Laterality;
                    pro.OrthoFastTrack = p.Proc.OrthoFastTrack;
                    pro.ProcedureID = p.Proc.ProcedureID;
                    pro.ProcedureText = p.Proc.ProcedureText;
                    pro.RequestID = ReqID;
                    pro.Site = p.Proc.Site; ;

                    pro.scar_Requests = sReq;
                }

                //Update Surgeons
                pro.scar_Surgeons.Clear();
                foreach (scar_Surgeons s in p.Surgeons)
                {
                    pro.scar_Surgeons.Add(db2.scar_Surgeons.Where(x=> x.SurgeonID == s.SurgeonID).FirstOrDefault());
                }
            }


            //Set State and Save
            db2.Entry(sReq).State = System.Data.Entity.EntityState.Modified;
            db2.SaveChanges();
        }
    }
于 2013-09-27T14:33:45.520 回答