Tôi đang gặp sự cố với Entity Framework 4.0. Tôi đang cố lưu đối tượng "Điều trị" có bộ sưu tập đối tượng "Phân đoạn". Bất cứ khi nào tôi cố gắng thêm/chỉnh sửa đối tượng Điều trị nơi tôi thêm 2 hoặc nhiều Phân đoạn mới, tôi nhận được lỗi sau:Lỗi với khung thực thể: AcceptChanges không thể tiếp tục vì các giá trị khóa của đối tượng xung đột với một đối tượng khác trong ObjectStateManager
The changes to the database were committed successfully, but an error occurred while updating the object context. The ObjectContext might be in an inconsistent state. Inner exception message: AcceptChanges cannot continue because the object's key values conflict with another object in the ObjectStateManager. Make sure that the key values are unique before calling AcceptChanges.
Đây là phương pháp lưu tôi đang sử dụng. Cột "SegmentID" là PK cho "Phân đoạn" và nó là một số nguyên được đặt thành tăng tự động trong DB (MS SQL 2008). Theo mặc định, "SegmentID" được đặt thành 0 cho đến khi nó nhận được phân đoạn được cập nhật từ DB.
public bool Save(Treatment myTreatment)
{
bool result = false;
using (tamcEntities db = new tamcEntities())
{
// IF NEW TREATMENT, CREATE IT AND ADD TO DB
if (myTreatment.Treatment_ID == 0)
{
db.Treatments.AddObject(myTreatment);
result = (db.SaveChanges() != 0);
}
// IF EXISTING TREATMENT, FIND EXISTING TREATMENT IN DB, AND UPDATE IT
else
{
List<string> treatmentIncludes = new List<string>();
treatmentIncludes.Add("Segments");
Treatment myTmt = (from x in db.Treatments
where x.Treatment_ID == myTreatment.Treatment_ID
select x).WithIncludes(treatmentIncludes).FirstOrDefault();
if (myTmt != null)
{
myTmt.Comment = myTreatment.Comment;
myTmt.Cost = myTreatment.Cost;
myTmt.CostItemDrain = myTreatment.CostItemDrain;
myTmt.CostItemE2E = myTreatment.CostItemE2E;
myTmt.CostItemEnhan = myTreatment.CostItemEnhan;
myTmt.CostItemEnv = myTreatment.CostItemEnv;
myTmt.CostItemGuard = myTreatment.CostItemGuard;
myTmt.CostItemOther = myTreatment.CostItemOther;
myTmt.CostItemPed = myTreatment.CostItemPed;
myTmt.CostItemSub = myTreatment.CostItemSub;
myTmt.CostItemTraffic = myTreatment.CostItemTraffic;
myTmt.CostItemUtl = myTreatment.CostItemUtl;
myTmt.Create_DateTime = myTreatment.Create_DateTime;
myTmt.Create_Entity = myTreatment.Create_Entity;
myTmt.Create_User = myTreatment.Create_User;
myTmt.Description = myTreatment.Description;
myTmt.Improvement_Type = myTreatment.Improvement_Type;
myTmt.Jurisdiction = myTreatment.Jurisdiction;
myTmt.Last_Update_DateTime = myTreatment.Last_Update_DateTime;
myTmt.Last_Update_Entity = myTreatment.Last_Update_Entity;
myTmt.Last_Update_User = myTreatment.Last_Update_User;
myTmt.Life_Expectancy = myTreatment.Life_Expectancy;
myTmt.MDOTJobID = myTreatment.MDOTJobID;
myTmt.Planned = myTreatment.Planned;
myTmt.Project_Classification = myTreatment.Project_Classification;
myTmt.ProjectID = myTreatment.ProjectID;
myTmt.Quantity = myTreatment.Quantity;
myTmt.SurfaceTypeAfter = myTreatment.SurfaceTypeAfter;
myTmt.tmp_treat = myTreatment.tmp_treat;
myTmt.Treatment_Date = myTreatment.Treatment_Date;
myTmt.Unit_of_Measure = myTreatment.Unit_of_Measure;
// DELETE MISSING SEGMENTS THAT ARE NO LONGER PART OF THE TREATMENT
List<int> segmentIDsToKeep = myTreatment.Segments.Select(x => x.SegmentID).ToList();
myTmt.Segments.Where(x => !segmentIDsToKeep.Contains(x.SegmentID)).ToList().ForEach(x => db.Segments.DeleteObject(x));
// ITERATE OVER EACH SEGMENT AND INSERT OR UPDATE IT
foreach (Segment s in myTreatment.Segments)
{
if (!string.IsNullOrWhiteSpace(s.PR) && !string.IsNullOrWhiteSpace(s.BMP.ToString()) && !string.IsNullOrWhiteSpace(s.EMP.ToString()))
{
Segment mySegment = new Segment();
// IF EXISTING SEGMENT, FIND EXISTING SEGMENT IN DB, AND UPDATE IT
if (s.SegmentID != 0)
{
mySegment = (from x in myTmt.Segments
where x.SegmentID == s.SegmentID
select x).FirstOrDefault();
}
mySegment.ActualLength = s.ActualLength;
mySegment.BMP = s.BMP;
mySegment.Create_DateTime = s.Create_DateTime;
mySegment.Create_Entity = s.Create_Entity;
mySegment.Create_User = s.Create_User;
mySegment.EMP = s.EMP;
mySegment.HasRequiredHPMS = s.HasRequiredHPMS;
mySegment.Lanes = s.Lanes;
mySegment.Last_Update_DateTime = s.Last_Update_DateTime;
mySegment.Last_Update_Entity = s.Last_Update_Entity;
mySegment.Last_Update_User = s.Last_Update_User;
mySegment.PASER_Rating = s.PASER_Rating;
mySegment.PR = s.PR;
mySegment.RoadName = s.RoadName;
mySegment.SurfaceType = s.SurfaceType;
mySegment.Treatment_ID = s.Treatment_ID;
mySegment.Version = s.Version;
// If the BMP is greater than the EMP, swap them.
if (mySegment.BMP > mySegment.EMP)
{
decimal tempBMP = mySegment.BMP;
decimal tempEMP = mySegment.EMP;
mySegment.BMP = tempEMP;
mySegment.EMP = tempBMP;
}
// IF NEW SEGMENT, ADD IT
if (s.SegmentID == 0)
{
myTmt.Segments.Add(mySegment);
}
}
}
result = (db.SaveChanges(SaveOptions.AcceptAllChangesAfterSave) != 0);
}
}
}
return result;
}
này đang làm việc cho tôi. –