none
How to merge self-tracking entities? RRS feed

  • Question

  • Hi all! I have a problem when try to merge STE. 

    private Objects _obj1; private Elements _elem1; private Properties _prop1; private Properties _prop2; private Properties _prop3; private Properties _prop4; private void InitializeEntities()         {             _obj1 = new Objects                         {                             ObjectId = Guid.NewGuid()                         };             _elem1 = new Elements                          {                              CreationTime = DateTime.Now,                              ObjectId = _obj1.ObjectId,                              Name = "testElem#1"                          };             _prop1 = new Properties                          {                              PropertyId = Guid.NewGuid(),                              ObjectId = _obj1.ObjectId,                              Name = "ObjProperty#1",                              Value = "TestValue#1"                          };             _prop2 = new Properties                          {                              PropertyId = Guid.NewGuid(),                              ObjectId = _obj1.ObjectId,                              Name = "ObjProperty#2",                              Value = "TestValue#2"                          };             _prop3 = new Properties                          {                              PropertyId = Guid.NewGuid(),                              ElementId = _elem1.ElementId,                              ObjectId = _obj1.ObjectId,                              Name = "ElemProperty#1",                              Value = "TestValue#3"                          };             _prop4 = new Properties                          {                              PropertyId = Guid.NewGuid(),                              ElementId = _elem1.ElementId,                              ObjectId = _obj1.ObjectId,                              Name = "ElemProperty#2",                              Value = "TestValue#4"                          };             _elem1.Properties.Add(_prop3);             _elem1.Properties.Add(_prop4);             _obj1.Properties.Add(_prop1);             _obj1.Properties.Add(_prop2);             _obj1.Elements.Add(_elem1);         }

    using (var context = new TEntities())             {                 _objects = context.CreateObjectSet<Objects>();                 InitializeEntities();                 Save(context, _obj1);             }             using (var context = new TEntities())             {                 var objSet = context.CreateObjectSet<Objects>().Include("Elements").Include("Properties");                 var targetobject = objSet.Where(x => x.ObjectId == _obj1.ObjectId).FirstOrDefault();                 var targetElement = targetobject.Elements.Where(x => x.ElementId == _elem1.ElementId).FirstOrDefault();                 var properties = ChangeElementProperties(targetElement.Properties);                 targetElement.Properties.Clear();                 targetElement.StopTracking();                 foreach (var property in properties)                 {                     _elem1.Properties.Add(property);                 }                 Save(context, _obj1);             }

    private List<Properties> ChangeElementProperties(TrackableCollection<Properties> objectProperties)
            {
                var tempPropertiesCollection = new List<Properties>();

                var tempProp1 = new Properties();
                _prop3.AcceptChanges();
                _prop3.StopTracking();
                tempProp1 = _prop3;

                var tempProp2 = new Properties();
                _prop4.AcceptChanges();
                _prop4.StopTracking();
                tempProp2 = _prop4;

                tempProp1.Name = "1";
                tempProp1.Value = "1";
                tempProp1.MarkAsModified();
                tempProp1.StartTracking();

                tempProp2.Name = "2";
                tempProp2.Value = "2";
                tempProp2.MarkAsModified();
                tempProp2.StartTracking();

                tempPropertiesCollection.Add(tempProp1.MarkAsModified());
                tempPropertiesCollection.Add(tempProp2.MarkAsModified());

                return tempPropertiesCollection;
            }

    private void Save(TEntities context, Objects obj1)         {             try             {                 context.ApplyChanges("TEntities.Objects", obj1);                 context.SaveChanges(SaveOptions.DetectChangesBeforeSave);             }             catch (Exception e)             {             }         }


    When the Save method is calling after changing element properties occur the exception : "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. 

    How can I solve this problem?




    • Edited by Gepard_vvk Thursday, May 17, 2012 12:42 PM
    Thursday, May 17, 2012 12:28 PM

All replies

  • Obviously, you could find a point in this code, where STE with duplicate PK being added to context and modify existing entry instead of adding new one.
    Thursday, May 17, 2012 12:53 PM
  • Obviously, you could find a point in this code, where STE with duplicate PK being added to context and modify existing entry instead of adding new one.

    I need to change an existing entry, rather than add a new.

    Thursday, May 17, 2012 1:03 PM
  • But you are trying to add existing Properties to the same Element. What`s the meaning?

    There are two change trackers: STE change tracker and context change tracker. When you are trying to clear properties collection and then add modified items back, they are out of sync.

    Thursday, May 17, 2012 2:06 PM
  • I have described in greater detail the issue here http://stackoverflow.com/questions/10632752/merge-self-tracking-entities


    • Edited by Gepard_vvk Friday, May 18, 2012 5:25 AM
    Friday, May 18, 2012 5:24 AM