示例#1
0
 /// <summary>
 /// Force initialization of all non-lazy collections encountered during
 /// the current two-phase load (actually, this is a no-op, unless this
 /// is the "outermost" load)
 /// </summary>
 /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
 public async Task InitializeNonLazyCollectionsAsync(CancellationToken cancellationToken)
 {
     cancellationToken.ThrowIfCancellationRequested();
     if (loadCounter == 0)
     {
         log.Debug("initializing non-lazy collections");
         //do this work only at the very highest level of the load
         loadCounter++;                 //don't let this method be called recursively
         try
         {
             while (nonlazyCollections.Count > 0)
             {
                 //note that each iteration of the loop may add new elements
                 IPersistentCollection tempObject = nonlazyCollections[nonlazyCollections.Count - 1];
                 nonlazyCollections.RemoveAt(nonlazyCollections.Count - 1);
                 await(tempObject.ForceInitializationAsync(cancellationToken)).ConfigureAwait(false);
             }
         }
         finally
         {
             loadCounter--;
             ClearNullProperties();
         }
     }
 }
示例#2
0
        private static Task PrepareCollectionForUpdateAsync(IPersistentCollection collection, CollectionEntry entry, ISessionFactoryImplementor factory, CancellationToken cancellationToken)
        {
            //1. record the collection role that this collection is referenced by
            //2. decide if the collection needs deleting/creating/updating (but don't actually schedule the action yet)

            if (entry.IsProcessed)
            {
                throw new AssertionFailure("collection was processed twice by flush()");
            }
            if (cancellationToken.IsCancellationRequested)
            {
                return(Task.FromCanceled <object>(cancellationToken));
            }
            try
            {
                entry.IsProcessed = true;

                ICollectionPersister loadedPersister  = entry.LoadedPersister;
                ICollectionPersister currentPersister = entry.CurrentPersister;
                if (loadedPersister != null || currentPersister != null)
                {
                    // it is or was referenced _somewhere_
                    bool ownerChanged = loadedPersister != currentPersister ||
                                        !currentPersister.KeyType.IsEqual(entry.LoadedKey, entry.CurrentKey, factory);

                    if (ownerChanged)
                    {
                        // do a check
                        bool orphanDeleteAndRoleChanged = loadedPersister != null &&
                                                          currentPersister != null && loadedPersister.HasOrphanDelete;

                        if (orphanDeleteAndRoleChanged)
                        {
                            return(Task.FromException <object>(new HibernateException("Don't change the reference to a collection with cascade=\"all-delete-orphan\": " + loadedPersister.Role)));
                        }

                        // do the work
                        if (currentPersister != null)
                        {
                            entry.IsDorecreate = true;                             // we will need to create new entries
                        }

                        if (loadedPersister != null)
                        {
                            entry.IsDoremove = true;                             // we will need to remove ye olde entries
                            if (entry.IsDorecreate)
                            {
                                log.Debug("Forcing collection initialization");
                                return(collection.ForceInitializationAsync(cancellationToken));                                // force initialize!
                            }
                        }
                    }
                    else if (collection.IsDirty)
                    {
                        // else if it's elements changed
                        entry.IsDoupdate = true;
                    }
                }
                return(Task.CompletedTask);
            }
            catch (System.Exception ex)
            {
                return(Task.FromException <object>(ex));
            }
        }