0

詳細

多対多の関係を作成するために、2 つのテーブル (Procedures、Surgeons) とルックアップ テーブル (ProcSurg) があります。

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

1 つの要求に複数の処置を含めることができ、各処置に複数の外科医を含めることができます。

同じ Surgeon を共有する 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();
        }
        
    }

私はレコードを保存するためにいくつかの異なる方法を試しましたが、これは私が正しく行うことに最も近い方法です.

外科医を実体に結びつけ、次に手術に結びつける方法に何か関係があるように感じます。どこで答えを見つけることができるかについての助け、アイデア、または提案は素晴らしいでしょう!

私は 1 週間以上にわたって Google を際限なく検索しており、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

良い形を保ちながら、私はそれを理解したと思うので、私の答えを投稿します. 多分それは将来誰かを助けるでしょう。

保存を完全に書き直して、以前使用していた多くの無駄なコードを切り取り、DB への呼び出しを減らしました。上記に投稿しなかった他の方法があり、記録の他の部分を 1 つの方法に要約して保存しました。

基本的に、DB からレコードとその結合テーブルを取得し、更新が必要なすべてのフィールド/結合テーブルを反復処理して、DB に保存します。(今では非常に明白に思えますが、以前にこの方法を試しましたが、この方法で試した最初の数回はうまくいかなかったので、何か問題があったに違いありません。)

それが 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 に答える