开发者

Maintain denormalized data with NHibernate EventListener

I have one bit of denormalized data used for performance reasons and I'm trying to maintain the data with an NHibernate event listener rather than a trigger. I'm not convinced this is the best approach, but I'm neck deep into it and I want to figure this out before moving on. I'm getting following error:

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

Here's the code to make happen:

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

and the event listener:

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 w开发者_JS百科here l.Business.BusinessId = :businessId") 
            .SetParameter("businessId", business.BusinessId) 
            .List<BusinessCategoryLink>();

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


This doesn't look like it's related to NHibernate, but rather the way C# handles iterators, and specifically Enumerations. I'm kind of guessing, but I think it's because you're modifying the value of an enumeration on this line: link.Location = business.Location;. A quick google search tells me that the Enumerator.Current property is read-only (which is what is used when you use the foreach construct). I bet using a regular for loop will solve this problem.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜