Exemple #1
0
 /// <summary>
 /// Initializes a new instance.
 /// </summary>
 internal ChangeEntry(ChangeType changeType, IUberMap map, object entity)
 {
     UberMap    = map;
     ChangeType = changeType;
     Entity     = entity;
     MetaEntity = MetaEntity.Locate(entity);
 }
Exemple #2
0
        /// <summary>
        /// Captures the current child entities of this instance for the given member.
        /// </summary>
        internal static void CaptureMetaMemberChilds(this MetaEntity meta, IUberMember member)
        {
            var entity = meta.Entity;

            if (member.DependencyMode == MemberDependencyMode.Child &&
                member.ElementInfo.CanRead &&
                member.ElementInfo.ElementType.IsListAlike())
            {
                var type = member.ElementInfo.ElementType.ListAlikeMemberType();
                if (type != null && (type.IsClass || type.IsInterface))
                {
                    HashSet <object> portion = null;
                    if (!meta.ChildDependencies.TryGetValue(member.Name, out portion))
                    {
                        meta.ChildDependencies.Add(member.Name, (portion = new HashSet <object>()));
                    }

                    portion.Clear(); if (meta.UberMap.Repository.TrackChildEntities)
                    {
                        var iter = member.ElementInfo.GetValue(entity) as IEnumerable;
                        foreach (var obj in iter)
                        {
                            if (obj != null)
                            {
                                portion.Add(obj);
                            }
                        }
                    }
                }
            }
        }
		/// <summary>
		/// Returns the meta entity associated with the given object, creating it if needed and
		/// requested. Returns null otherwise.
		/// </summary>
		/// <param name="entity">The object to obtain its meta entity from.</param>
		/// <param name="create">True to create the meta entity if it did not exist.</param>
		/// <returns>The requested meta entity, or null.</returns>
		public static MetaEntity Locate(object entity, bool create = true)
		{
			if (entity == null) throw new ArgumentNullException("entity", "Entity cannot be null.");

			var type = entity.GetType();
			if (!type.IsClass) throw new InvalidOperationException(
				"Entity '{0}' of type '{1}' is not a class.".FormatWith(entity.Sketch(), type.EasyName()));

			lock (entity) // Yes, I know... but I want to use at most a local lock on the entity!
			{
				AttributeCollection list = TypeDescriptor.GetAttributes(entity);
				MetaEntity meta = list.OfType<MetaEntity>().FirstOrDefault();

				if (meta == null && create)
				{
					meta = new MetaEntity(); TypeDescriptor.AddAttributes(entity, meta);
					meta._SerialId = ++Uber.MetaEntityLastSerial;
					meta._EntityType = type;
				}
				if (meta != null && !meta.HasValidEntity)
				{
					meta._WeakReference = new WeakReference(entity);
				}
				return meta;
			}
		}
Exemple #4
0
        /// <summary>
        /// Returns an ad-hoc record containing the changes experimented by the entity since the
        /// last time its internal record was captured, or null if no changes can be detected.
        /// </summary>
        internal static IRecord GetRecordChanges(this MetaEntity meta)
        {
            object obj = meta.Entity; if (obj == null)

            {
                return(null);
            }

            if (meta.UberMap == null)
            {
                return(null);
            }
            if (meta.Record == null)
            {
                return(null);
            }

            var current = new Core.Concrete.Record(meta.UberMap.Schema);

            meta.UberMap.WriteRecord(obj, current);

            var changes = current.Changes(meta.Record); current.Dispose();

            return(changes);
        }
Exemple #5
0
        /// <summary>
        /// Returns the meta entity associated with the given object, creating it if needed and
        /// requested. Returns null otherwise.
        /// </summary>
        /// <param name="entity">The object to obtain its meta entity from.</param>
        /// <param name="create">True to create the meta entity if it did not exist.</param>
        /// <returns>The requested meta entity, or null.</returns>
        public static MetaEntity Locate(object entity, bool create = true)
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity", "Entity cannot be null.");
            }

            var type = entity.GetType();

            if (!type.IsClass)
            {
                throw new InvalidOperationException(
                          "Entity '{0}' of type '{1}' is not a class.".FormatWith(entity.Sketch(), type.EasyName()));
            }

            lock (entity)             // Yes, I know... but I want to use at most a local lock on the entity!
            {
                AttributeCollection list = TypeDescriptor.GetAttributes(entity);
                MetaEntity          meta = list.OfType <MetaEntity>().FirstOrDefault();

                if (meta == null && create)
                {
                    meta             = new MetaEntity(); TypeDescriptor.AddAttributes(entity, meta);
                    meta._SerialId   = ++Uber.MetaEntityLastSerial;
                    meta._EntityType = type;
                }
                if (meta != null && !meta.HasValidEntity)
                {
                    meta._WeakReference = new WeakReference(entity);
                }
                return(meta);
            }
        }
Exemple #6
0
        /// <summary>
        /// Returns whether this child entity requires a save operation.
        /// </summary>
        internal static bool DoesMetaNeedSave(this MetaEntity child, bool cascade, object origin = null)
        {
            if (child.Map == null)
            {
                return(true);
            }
            if (child.HasRecordChanges())
            {
                return(true);
            }

            var list = child.GetRemovedChilds(forgetRemoved: false);
            var need = list.Count != 0;

            list.Clear(); list = null;
            if (need)
            {
                return(true);
            }

            if (cascade)
            {
                list = child.GetDependencies(child.UberMap, MemberDependencyMode.Child);
                foreach (var obj in list)
                {
                    if (obj == null)
                    {
                        continue;
                    }
                    var type = obj.GetType(); if (!type.IsClass && !type.IsInterface)
                    {
                        continue;
                    }
                    if (object.ReferenceEquals(origin, obj))
                    {
                        continue;
                    }

                    var meta = MetaEntity.Locate(obj);
                    var temp = meta.UberMap ?? child.UberMap.Repository.LocateUberMap(type);
                    if (temp == null)
                    {
                        throw new NotFoundException("Cannot find map for type '{0}'.".FormatWith(type.EasyName()));
                    }

                    if (meta.DoesMetaNeedSave(cascade: false))
                    {
                        need = true; break;
                    }
                }
                list.Clear(); list = null;
                if (need)
                {
                    return(true);
                }
            }

            return(false);
        }
 /// <summary>
 /// Initializes a new instance.
 /// </summary>
 /// <param name="map">The map this command will be associated with.</param>
 /// <param name="entity">The entity affected by this operation.</param>
 protected MetaOperation(DataMap <T> map, T entity) : base(map)
 {
     if (entity == null)
     {
         throw new ArgumentNullException("entity", "Entity cannot be null.");
     }
     _Entity     = entity;
     _MetaEntity = MetaEntity.Locate(entity);
 }
Exemple #8
0
        /// <summary>
        /// Returns whether the entity has experimented any changes since the last time its
        /// internal record was captured, or not.
        /// </summary>
        internal static bool HasRecordChanges(this MetaEntity meta)
        {
            var  changes = meta.GetRecordChanges();
            bool r       = changes != null;

            if (changes != null)
            {
                changes.Dispose(disposeSchema: true);
            }
            return(r);
        }
        /// <summary>
        /// Returns a list containing the dependencies of the given entity whose mode match the
        /// one given.
        /// </summary>
        internal static List <object> GetDependencies(this MetaEntity meta, IUberMap map, MemberDependencyMode mode)
        {
            var list   = new List <object>();
            var entity = meta.Entity; if (entity != null && map != null && !map.IsDisposed)

            {
                foreach (var member in (IEnumerable <IUberMember>)map.Members)
                {
                    if (member.DependencyMode != mode)
                    {
                        continue;
                    }
                    if (!member.ElementInfo.CanRead)
                    {
                        continue;
                    }

                    var source = member.ElementInfo.GetValue(entity);
                    if (source == null)
                    {
                        continue;
                    }

                    var type = source.GetType(); if (!type.IsListAlike())
                    {
                        if (type.IsClass)
                        {
                            list.Add(source);
                        }
                    }
                    else
                    {
                        type = type.ListAlikeMemberType(); if (type.IsClass)
                        {
                            var iter = source as IEnumerable;
                            foreach (var item in iter)
                            {
                                if (item != null)
                                {
                                    list.Add(item);
                                }
                            }
                        }
                    }
                }
            }
            return(list);
        }
Exemple #10
0
        /// <summary>
        /// Generates a delete core command for the given entity, or returns null if such
        /// command cannot be generated for whatever reasons.
        /// </summary>
        internal static IDeleteCommand GenerateDeleteCommand(this IUberMap map, object entity)
        {
            if (entity == null)
            {
                return(null);
            }
            if (map == null || map.IsDisposed || !map.IsValidated)
            {
                return(null);
            }

            IDeleteCommand cmd = null;

            MetaEntity meta = MetaEntity.Locate(entity, create: true); if (meta.Record == null)
            {
                var record = new Core.Concrete.Record(map.Schema);
                map.WriteRecord(entity, record);
                meta.Record = record;
            }

            var id = map.ExtractId(meta.Record);

            if (id != null)
            {
                cmd = map.Link.Engine.CreateDeleteCommand(map.Link, x => map.Table);
                if (map.Discriminator != null)
                {
                    cmd.Where(map.Discriminator);
                }

                var tag = new DynamicNode.Argument("x");
                for (int i = 0; i < id.Count; i++)
                {
                    var left = new DynamicNode.GetMember(tag, id.Schema[i].ColumnName);
                    var bin  = new DynamicNode.Binary(left, ExpressionType.Equal, id[i]);
                    cmd.Where(x => bin);
                    left.Dispose();
                    bin.Dispose();
                }
                tag.Dispose();
                id.Dispose();
            }

            return(cmd);
        }
        /// <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)
        {
            if (disposing)
            {
                try
                {
                    if (Repository != null && !Repository.IsDisposed)
                    {
                        lock (Repository.MasterLock) { Repository.UberOperations.Remove(this); }
                    }
                }
                catch { }
            }

            _MetaEntity = null;
            _Entity     = null;

            base.OnDispose(disposing);
        }
        /// <summary>
        /// Returns a list with the child dependencies that have been removed since the last
        /// time those were captured.
        /// </summary>
        internal static List <object> GetRemovedChilds(this MetaEntity meta, bool forgetRemoved)
        {
            var list   = new List <object>();
            var entity = meta.Entity; if (entity != null)

            {
                var type = entity.GetType();
                foreach (var kvp in meta.ChildDependencies)
                {
                    // Obtaining the current state...
                    var info = ElementInfo.Create(type, kvp.Key, flags: TypeEx.FlattenInstancePublicAndHidden);
                    if (!info.CanRead)
                    {
                        continue;
                    }
                    var curr = ((IEnumerable)info.GetValue(entity)).Cast <object>().ToList();

                    // Adding the entities that has been removed...
                    foreach (var item in kvp.Value)
                    {
                        if (!curr.Contains(item))
                        {
                            list.Add(item);
                        }
                    }
                    curr.Clear(); curr = null;

                    if (forgetRemoved)                     // Foget removed childs if such is requested
                    {
                        foreach (var item in list)
                        {
                            kvp.Value.Remove(item);
                        }
                    }
                }
            }
            return(list);
        }
 /// <summary>
 /// Returns all the operations associated with the given entity, or null.
 /// </summary>
 internal List <IUberOperation> FindAllMeta(MetaEntity meta)
 {
     return(_Items.FindAll(x => object.ReferenceEquals(x.MetaEntity, meta)));
 }
 /// <summary>
 /// Returns the last operation associated with the given entity, or null.
 /// </summary>
 internal IUberOperation FindLastMeta(MetaEntity meta)
 {
     return(_Items.FindLast(x => object.ReferenceEquals(x.MetaEntity, meta)));
 }
 /// <summary>
 /// Invoked to obtain additional info when tracing an empty command.
 /// </summary>
 protected override string OnTraceCommandEmpty()
 {
     return(MetaEntity == null ? string.Empty : MetaEntity.ToString());
 }
        /// <summary>
        /// Validates that the row version captured in the meta-entity is the same as the current
        /// one in the database, throwing an exception if a change is detected.
        /// </summary>
        internal static void ValidateRowVersion(this MetaEntity meta)
        {
            var entity = meta.Entity; if (entity == null)

            {
                return;
            }

            if (meta.UberMap == null)
            {
                return;
            }
            if (meta.Record == null)
            {
                return;
            }

            var vc = meta.UberMap.VersionColumn;

            if (vc.Name == null)
            {
                return;
            }

            // Getting the most updated record, if any...
            var cmd = meta.UberMap.Link.From(x => meta.UberMap.Table);
            var tag = new DynamicNode.Argument("x");
            var id  = meta.UberMap.ExtractId(meta.Record);

            if (id == null)
            {
                throw new InvalidOperationException(
                          "Cannot obtain identity from entity '{0}'".FormatWith(meta));
            }

            for (int i = 0; i < id.Count; i++)
            {
                var left = new DynamicNode.GetMember(tag, id.Schema[i].ColumnName);
                var bin  = new DynamicNode.Binary(left, ExpressionType.Equal, id[i]);
                cmd.Where(x => bin);
                bin.Dispose();
                left.Dispose();
            }
            id.Dispose();
            tag.Dispose();

            var rec = (IRecord)cmd.First();

            cmd.Dispose();
            if (rec == null)
            {
                return;
            }

            // Comparing values....
            string captured = vc.ValueToString == null
                                ? meta.Record[vc.Name].Sketch()
                                : vc.ValueToString(meta.Record[vc.Name]);

            string current = vc.ValueToString == null
                                ? rec[vc.Name].Sketch()
                                : vc.ValueToString(rec[vc.Name]);

            if (string.Compare(captured, current) != 0)
            {
                throw new ChangedException(
                          "Captured version '{0}' for entity '{1}' differs from the database's current one '{2}'."
                          .FormatWith(captured, meta, current));
            }
        }
Exemple #17
0
        /// <summary>
        /// Generates an update core command for the given entity, or returns null if such
        /// command cannot be generated for whatever reasons.
        /// </summary>
        internal static IUpdateCommand GenerateUpdateCommand(this IUberMap map, object entity)
        {
            if (entity == null)
            {
                return(null);
            }
            if (map == null || map.IsDisposed || !map.IsValidated)
            {
                return(null);
            }

            IUpdateCommand cmd = null;

            MetaEntity meta = MetaEntity.Locate(entity, create: true); if (meta.Record == null)
            {
                var record = new Core.Concrete.Record(map.Schema);
                map.WriteRecord(entity, record);
                meta.Record = record;
            }

            var changes = meta.GetRecordChanges(); if (changes == null)
            {
                return(null);
            }

            var num = changes.Schema.Count(x => !x.IsReadOnlyColumn);

            if (num != 0)
            {
                var id = map.ExtractId(meta.Record); if (id != null)
                {
                    cmd = map.Link.Engine.CreateUpdateCommand(map.Link, x => map.Table);
                    if (map.Discriminator != null)
                    {
                        cmd.Where(map.Discriminator);
                    }

                    var tag = new DynamicNode.Argument("x");
                    for (int i = 0; i < id.Count; i++)
                    {
                        var left = new DynamicNode.GetMember(tag, id.Schema[i].ColumnName);
                        var bin  = new DynamicNode.Binary(left, ExpressionType.Equal, id[i]);
                        cmd.Where(x => bin);
                        left.Dispose();
                        bin.Dispose();
                    }

                    for (int i = 0; i < changes.Count; i++)
                    {
                        if (changes.Schema[i].IsReadOnlyColumn)
                        {
                            continue;
                        }

                        var node = new DynamicNode.SetMember(tag, changes.Schema[i].ColumnName, changes[i]);
                        cmd.Columns(x => node);
                        node.Dispose();
                    }

                    tag.Dispose();
                    id.Dispose();
                }
            }
            changes.Dispose(disposeSchema: true);

            return(cmd);
        }
Exemple #18
0
        /// <summary>
        /// Executes the command if it has not been executed yet in this instance. Returns true
        /// if a new record is available, or false otherwise.
        /// </summary>
        public bool MoveNext()
        {
            if (IsDisposed)
            {
                throw new ObjectDisposedException(this.ToString());
            }
            try
            {
                if (_CoreCommand == null)                 // Preparing iterations...
                {
                    _CoreCommand = _Command.GenerateCoreCommand(); if (_CoreCommand == null)
                    {
                        throw new CannotCreateException("Cannot create a core query command for this '{0}'.".FormatWith(this));
                    }

                    _Enumerator = _CoreCommand.GetEnumerator(); if (_Enumerator == null)
                    {
                        throw new CannotCreateException("Cannot create a core query enumerator for this '{0}'.".FormatWith(this));
                    }

                    DebugEx.IndentWriteLine("\n- Query: entering '{0}'...".FormatWith(_Command.TraceString()));
                    _Indented = true;
                }

                _Current = null; bool r = _Enumerator.MoveNext(); if (r)                 // Current iteration...
                {
                    var record     = _Enumerator.CurrentRecord;
                    var disposable = true;
                    var map        = _Command.Map;

                    lock (map.Repository.MasterLock)
                    {
                        if (map.TrackEntities)
                        {
                            var node = map.MetaEntities.FindNode(record); if (node != null)
                            {
                                foreach (var meta in node)
                                {
                                    T obj = (T)meta.Entity; if (obj == null)
                                    {
                                        DebugEx.IndentWriteLine("\n- Query: meta invalid '{0}'.".FormatWith(meta));
                                        DebugEx.Unindent();
                                        continue;
                                    }

                                    if (_Current == null)
                                    {
                                        _Current = obj;
                                    }
                                    else
                                    if (map.ProxyType != null &&
                                        map.ProxyType != _Current.GetType() &&
                                        map.ProxyType == obj.GetType())
                                    {
                                        _Current = obj;
                                    }

                                    if (meta.Completed)
                                    {
                                        DebugEx.IndentWriteLine("\n- Query: meta completed '{0}'.".FormatWith(meta));
                                        DebugEx.Unindent();
                                        continue;
                                    }

                                    DebugEx.IndentWriteLine("\n- Query: hydrating meta '{0}'.".FormatWith(meta));
                                    meta.Record = record.Clone();
                                    map.LoadEntity(meta.Record, obj);
                                    map.CompleteMembers(meta);
                                    DebugEx.Unindent();
                                }
                            }
                        }

                        if (_Current == null)
                        {
                            DebugEx.IndentWriteLine("\n- Query: new meta '{0}({1})'.".FormatWith(map.EntityType.EasyName(), record));
                            _Current     = map.NewEntity(); var meta = MetaEntity.Locate(_Current);
                            meta.Record  = record; disposable = false;
                            meta.UberMap = map; if (map.TrackEntities)
                            {
                                map.MetaEntities.Add(meta);
                            }
                            map.LoadEntity(meta.Record, _Current);
                            map.CompleteMembers(meta);
                            DebugEx.Unindent();
                        }
                    }

                    if (disposable)
                    {
                        record.Dispose();
                    }
                }
                else
                {
                    Reset();
                }

                return(r);
            }
            catch
            {
                try { Dispose(); }
                catch { }

                throw;
            }
        }
Exemple #19
0
        /// <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();
                }
            }
        }
Exemple #20
0
        /// <summary>
        /// Invoked to execute this operation.
        /// </summary>
        internal void OnExecute(object origin = null)
        {
            lock (Repository.MasterLock)
            {
                List <object>  list   = null;
                ChangeEntry    change = null;
                IDeleteCommand cmd    = null;

                DebugEx.IndentWriteLine("\n- Preparing 'Delete({0})'...", MetaEntity);
                try
                {
                    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.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()));
                        }

                        var op = map.Delete(obj);
                        try { ((IUberOperation)op).OnExecute(origin: Entity); }
                        finally { op.Dispose(); }
                    }
                    list.Clear(); list = null;

                    cmd = Map.GenerateDeleteCommand(Entity);
                    if (cmd != null)
                    {
                        DebugEx.IndentWriteLine("\n- Executing '{0}'...", cmd);
                        try
                        {
                            MetaEntity.ValidateRowVersion();
                            int n = cmd.Execute();
                        }
                        finally { DebugEx.Unindent(); }
                    }
                    Map.Detach(Entity);

                    change = new ChangeEntry(ChangeType.Delete, Map, Entity);
                    Repository.ChangeEntries.Add(change);

                    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()));
                        }

                        change = new ChangeEntry(ChangeType.Refresh, map, obj);
                        Repository.ChangeEntries.Add(change);
                    }
                }
                finally
                {
                    if (cmd != null)
                    {
                        cmd.Dispose();
                    }
                    cmd = null;
                    if (list != null)
                    {
                        list.Clear();
                    }
                    list = null;
                    DebugEx.Unindent();
                }
            }
        }
Exemple #21
0
        /// <summary>
        /// Returns the string representation of this instance.
        /// </summary>
        /// <returns>A string containing the standard representation of this instance.</returns>
        public override string ToString()
        {
            var str = string.Format("{0}({1})", ChangeType, MetaEntity == null ? string.Empty : MetaEntity.ToString());

            return(str);
        }