Example #1
0
        /// <summary>
        /// Given a collection of entity instances that used to
        /// belong to the collection, and a collection of instances
        /// that currently belong, return a collection of orphans
        /// </summary>
        protected virtual ICollection GetOrphans(ICollection oldElements, ICollection currentElements, string entityName, ISessionImplementor session)
        {
            // short-circuit(s)
            if (currentElements.Count == 0)
            {
                // no new elements, the old list contains only Orphans
                return(oldElements);
            }
            if (oldElements.Count == 0)
            {
                // no old elements, so no Orphans neither
                return(oldElements);
            }

            if (currentElements.Count == oldElements.Count && currentElements.Cast <object>().SequenceEqual(oldElements.Cast <object>(), new IdentityEqualityComparer()))
            {
                return(Array.Empty <object>());
            }

            var   persister = session.Factory.GetEntityPersister(entityName);
            IType idType    = persister.IdentifierType;

            var currentObjects = new HashSet <object>(new TypeComparer(idType, session.Factory));

            foreach (object current in currentElements)
            {
                if (current != null)
                {
                    var id = ForeignKeys.GetIdentifier(persister, current);
                    if (id != null)
                    {
                        currentObjects.Add(id);
                    }
                }
            }

            List <object> res = new List <object>();

            // oldElements may contain new elements (one case when session.Save is called on new object with collection filled with new objects)
            foreach (object old in oldElements)
            {
                if (old != null)
                {
                    var id = ForeignKeys.GetIdentifier(persister, old);
                    if (id != null)
                    {
                        if (!currentObjects.Contains(id))
                        {
                            res.Add(old);
                        }
                    }
                }
            }

            return(res);
        }