2009-10-30 3 views
2

J'ai un bit de données dénormalisé utilisé pour des raisons de performances et j'essaie de maintenir les données avec un écouteur d'événement NHibernate plutôt qu'un déclencheur. Je ne suis pas convaincu que ce soit la meilleure approche, mais je suis au coude-cou et je veux comprendre cela avant de passer à autre chose. Je reçois l'erreur suivante:Maintenir les données dénormalisées avec NHibernate EventListener

System.InvalidOperationException : Collection was modified; enumeration operation may not execute. 
    System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource) 
    System.Collections.Generic.List`1.Enumerator.MoveNextRare() 
    System.Collections.Generic.List`1.Enumerator.MoveNext() 
    NHibernate.Engine.ActionQueue.ExecuteActions(IList list) 
    NHibernate.Engine.ActionQueue.ExecuteActions() 
NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions (IEventSource session) 
    NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event) 
    NHibernate.Impl.SessionImpl.Flush() 
    NHibernate.Transaction.AdoTransaction.Commit() 

Voici le code pour faire advenir:

using (var tx = session.BeginTransaction()) 
{ 
    var business = session 
     .Get<Business>(1234) 
     .ChangeZipCodeTo("92011"); 
    session.Update(business); 
    tx.Commit(); // error happens here 
} 

et l'écouteur d'événement:

public void OnPostUpdate(PostUpdateEvent @event) 
{ 
    var business = @event.Entity as Business; 
    if (business != null) 
    { 
     var links = @event.Session 
      .CreateQuery("select l from BusinessCategoryLink as l where l.Business.BusinessId = :businessId") 
      .SetParameter("businessId", business.BusinessId) 
      .List<BusinessCategoryLink>(); 

     foreach (var link in links) 
     { 
      link.Location = business.Location; 
      @event.Session.Update(link); 
     } 
    } 
} 
+0

Avez-vous trouvé une solution à ce problème? Je suis également confronté au même problème. – madaboutcode

+0

Non, je n'ai pas réussi à l'accomplir avec un écouteur d'événement. –

Répondre

1

Cela ne ressemble pas à elle est liée à NHibernate , mais plutôt la façon dont C# gère les itérateurs, et en particulier les énumérations. Je suis un peu deviner, mais je pense que c'est parce que vous modifiez la valeur d'une énumération sur cette ligne: link.Location = business.Location;. Une recherche rapide sur google m'indique que la propriété Enumerator.Current est en lecture seule (c'est ce qui est utilisé lorsque vous utilisez la construction foreach). Je parie que l'utilisation d'une boucle régulière for résoudra ce problème.

+0

J'ai vu ce genre d'erreur en essayant de supprimer un élément d'une liste tout en faisant un foreach dessus, mais je ne vois pas pourquoi c'est un problème dans ce cas. De toute évidence, je fais quelque chose de mal, alors une vieille boucle vaut vraiment le coup. Si seulement je pouvais me rappeler comment écrire un de ces ... –

+1

Ceci est définitivement un problème avec NHibernate. Si vous faites une recherche sur Google, vous en trouverez d'autres. Le problème est que vous modifiez la liste des actions que NHibernate doit effectuer lorsque vous effectuez l'appel .Update. –

Questions connexes