private CRecord AttachWithRelations(CRecord 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(_cRecords.GetExisting(entity)); } else { referenceTrackingList.Add(entity); } #endregion #region add/attach entity CRecord existingEntity = null; switch (insertMode) { case InsertMode.Add: existingEntity = _cRecords.Add(entity); break; case InsertMode.Attach: existingEntity = _cRecords.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 #endregion #region refresh existing entity based on merge options if (!ReferenceEquals(null, existingEntity) && !ReferenceEquals(existingEntity, entity)) { if (CRecords.MergeOption == MergeOption.OverwriteChanges) { Invoke(delegate { existingEntity.Refresh(entity, trackChanges: false); existingEntity.AcceptChanges(); }); } else if (CRecords.MergeOption == MergeOption.PreserveChanges) { Invoke(delegate { existingEntity.Refresh(entity, trackChanges: false, preserveExistingChanges: true); }); } } #endregion return(existingEntity); }