public When_loading_entities_with_include() { dataServiceMock = new Mock <ISimpleParentChildDataService>(); context = new SimpleParentChildDataContext(() => dataServiceMock.Object); dataServiceMock.Setup(x => x.GetChildSet(null, It.IsAny <Query>())) .Returns <ClientInfo, Query>((ci, q) => { var child = new Child { Id = 20, Parent = new Parent { Id = 10 } }; child.AcceptChanges(); child.Parent.AcceptChanges(); return(new QueryResult <Child> { Data = new[] { child } }); }); dataServiceMock.Setup(x => x.GetParentSet(null, It.IsAny <Query>())) .Returns <ClientInfo, Query>((ci, q) => { var parent = new Parent { Id = 10 }; parent.AcceptChanges(); return(new QueryResult <Parent> { Data = new[] { parent } }); }); }
public When_detaching_entities() { context = new SimpleParentChildDataContext(() => default(ISimpleParentChildDataService)); parent = new Parent(); child = new Child { Parent = parent }; parent.AcceptChanges(); child.AcceptChanges(); context.Attach(parent); }
private Parent AttachWithRelations(Parent entity, InsertMode insertMode = InsertMode.Attach, MergeOption mergeOption = MergeOption.AppendOnly, List <object> referenceTrackingList = null) { #region iteration tracking if (ReferenceEquals(null, referenceTrackingList)) { referenceTrackingList = new List <object>(); } if (referenceTrackingList.Contains(entity)) { return(_parentSet.GetExisting(entity)); } else { referenceTrackingList.Add(entity); } #endregion #region add/attach entity Parent existingEntity = null; switch (insertMode) { case InsertMode.Add: existingEntity = _parentSet.Add(entity); break; case InsertMode.Attach: existingEntity = _parentSet.Attach(entity); break; default: throw new Exception(string.Format("Implementation Exception: missing action for {0}", insertMode)); } if (!ReferenceEquals(null, existingEntity) && ReferenceEquals(existingEntity, entity)) { return(existingEntity); } #endregion #region attach relations recursively if (!ReferenceEquals(null, entity.Children)) { // register relation's collection changed event if entity is new to context if (ReferenceEquals(null, existingEntity)) { entity.Children.CollectionChanged += On_parent_children_collectionChanged; } // attach related entities to context if (entity.Children.Count > 0) { foreach (var item in entity.Children.ToArray()) { var existingRelatedEntity = AttachWithRelations(item, insertMode, mergeOption, referenceTrackingList); // update relation if entity is new to context or relation is new to entity if (ReferenceEquals(null, existingEntity) || !existingEntity.Children.Contains(item)) { if (!ReferenceEquals(null, existingRelatedEntity) && !ReferenceEquals(existingRelatedEntity, item)) { // check merge options if (!(mergeOption == MergeOption.PreserveChanges && existingRelatedEntity.ChangeTracker.OriginalValues.ContainsKey("Parent"))) { using (entity.ChangeTrackingPrevention()) { entity.Children.Replace(item, existingRelatedEntity); } using (existingRelatedEntity.ChangeTrackingPrevention()) { existingRelatedEntity.Parent = entity; } } } } } } } #endregion #region refresh existing entity based on merge options if (!ReferenceEquals(null, existingEntity) && !ReferenceEquals(existingEntity, entity)) { if (ParentSet.MergeOption == MergeOption.OverwriteChanges) { Invoke(delegate { existingEntity.Refresh(entity, trackChanges: false); existingEntity.AcceptChanges(); }); } else if (ParentSet.MergeOption == MergeOption.PreserveChanges) { Invoke(delegate { existingEntity.Refresh(entity, trackChanges: false, preserveExistingChanges: true); }); } } #endregion return(existingEntity); }