/// <summary> /// Invoked when disposing or finalizing this instance. /// </summary> /// <param name="disposing">True if the object is being disposed, false otherwise.</param> protected override void OnDispose(bool disposing) { try { if (_Command != null) { _Command.Dispose(); } } catch { } _Command = null; base.OnDispose(disposing); }
/// <summary> /// Invoked to execute this operation. /// </summary> internal void OnExecute(object origin = null) { lock (Repository.MasterLock) { List <object> list = null; ChangeEntry change = null; ChangeType changeType = MetaEntity.UberMap == null ? ChangeType.Insert : ChangeType.Update; IEnumerableCommand cmd = null; IRecord rec = null; DebugEx.IndentWriteLine("\n- Preparing '{1}({0})'...", MetaEntity, changeType); try { if (changeType == ChangeType.Update) { list = MetaEntity.GetRemovedChilds(forgetRemoved: true); foreach (var obj in list) { if (obj == null) { continue; } if (object.ReferenceEquals(obj, origin)) { continue; } var type = obj.GetType(); if (!type.IsClass && !type.IsInterface) { continue; } var meta = MetaEntity.Locate(obj); var map = meta.UberMap ?? Repository.LocateUberMap(type); if (map == null) { throw new NotFoundException("Cannot find map for type '{0}'.".FormatWith(type.EasyName())); } var op = map.Delete(obj); try { ((IUberOperation)op).OnExecute(origin: Entity); } finally { op.Dispose(); } } list.Clear(); list = null; } list = MetaEntity.GetDependencies(Map, MemberDependencyMode.Parent); foreach (var obj in list) { if (obj == null) { continue; } if (object.ReferenceEquals(obj, origin)) { continue; } var type = obj.GetType(); if (!type.IsClass && !type.IsInterface) { continue; } var meta = MetaEntity.Locate(obj); var map = meta.UberMap ?? Repository.LocateUberMap(type); if (map == null) { throw new NotFoundException("Cannot find map for type '{0}'.".FormatWith(type.EasyName())); } if (meta.DoesMetaNeedSave(true, origin: Entity)) { var op = map.Save(obj); try { ((IUberOperation)op).OnExecute(origin: Entity); } finally { op.Dispose(); } } else { change = new ChangeEntry(ChangeType.Refresh, map, obj); Repository.ChangeEntries.Add(change); } } if (changeType == ChangeType.Insert) { cmd = Map.GenerateInsertCommand(Entity); if (cmd == null) { throw new CannotCreateException("Cannot create an insert command for '{0}'.".FormatWith(MetaEntity)); } DebugEx.IndentWriteLine("\n- Executing '{0}'...", cmd); try { rec = (IRecord)cmd.First(); if (rec == null) { throw new CannotExecuteException("Cannot execute '{0}'.".FormatWith(cmd)); } } finally { DebugEx.Unindent(); } MetaEntity.Record = rec; Map.LoadEntity(rec, Entity); MetaEntity.UberMap = Map; if (Map.TrackEntities) { Map.MetaEntities.Add(MetaEntity); } MetaEntity.Completed = false; change = new ChangeEntry(ChangeType.Insert, Map, Entity); Repository.ChangeEntries.Add(change); } else if (changeType == ChangeType.Update) { cmd = Map.GenerateUpdateCommand(Entity); if (cmd != null) { DebugEx.IndentWriteLine("\n- Executing '{0}'...", cmd); try { MetaEntity.ValidateRowVersion(); rec = (IRecord)cmd.First(); if (rec == null) { throw new CannotExecuteException("Cannot execute '{0}'.".FormatWith(cmd)); } } finally { DebugEx.Unindent(); } MetaEntity.Record = rec; Map.LoadEntity(rec, Entity); MetaEntity.Completed = false; change = new ChangeEntry(ChangeType.Update, Map, Entity); Repository.ChangeEntries.Add(change); } else { change = new ChangeEntry(ChangeType.Refresh, Map, Entity); Repository.ChangeEntries.Add(change); } } list = MetaEntity.GetDependencies(Map, MemberDependencyMode.Child); foreach (var obj in list) { if (obj == null) { continue; } if (object.ReferenceEquals(obj, origin)) { continue; } var type = obj.GetType(); if (!type.IsClass && !type.IsInterface) { continue; } var meta = MetaEntity.Locate(obj); var map = meta.UberMap ?? Repository.LocateUberMap(type); if (map == null) { throw new NotFoundException("Cannot find map for type '{0}'.".FormatWith(type.EasyName())); } if (meta.DoesMetaNeedSave(cascade: true)) { var op = map.Save(obj); try { ((IUberOperation)op).OnExecute(origin: Entity); } finally { op.Dispose(); } } else { change = new ChangeEntry(ChangeType.Refresh, map, obj); Repository.ChangeEntries.Add(change); } } list.Clear(); list = null; } finally { if (cmd != null) { cmd.Dispose(); } cmd = null; if (list != null) { list.Clear(); } list = null; DebugEx.Unindent(); } } }