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