Sometimes it is necessary to take an action (e.g. modify another entity's persistent state) when certain conditions are true in another entity's OnValidate() method.

When doing so, DO throws: System.InvalidOperationException : Collection was modified; enumeration operation may not execute.

I'm assuming that it enumerates through the collection of modified entities and calls OnValidate on each entity. So if during this enumeration you modify another entity, it causes the collection to be modified.

I guess you can avoid this by making such changes in OnSetFieldValue instead of OnValidate. However, this poses a problem when using DisconnectedState. Imagine the following scenario.

I have an Order entity. Order has a status property of type enum, where the enum has 3 values (PendingConfirmation, Confirmed, Shipped). When Order.Status is set to shipped, I want to mark the corresponding Shipment entity's Shipment.ShippingDate = DateTime.Now.

In the disconnected scenario, the user is presented with a UI for the Order entity that has a combo box for the Status property. The combo box has the three enum values. If the user accidentally selects "Shipped", but then changes it to "Confirmed", and saves... then the history of actions is going to be replayed "Online".

So the model is going to receive a message for Order.Status == Shipped and then for Order.Status == Confirmed. In such a scenario, I don't want to mark Shipment.ShippingDate = DateTime.Now, because that should only happen when Order.Status == Shipped.

In such a scenario it is difficult to accomplish this through OnSetFieldValue. It is much easier to do it through OnValidate.

So, what do you suggest? Is it bad practice to modify other entities through OnValidate()? Or is this just some bug that can be easily fixed?

This thread was imported from our support forum. The original discussion may contain more detailed answer.

asked May 23 '10 at 23:15

ara's gravatar image

ara
395828791


One Answer:

I suspect this is related to registration in validation queue: OnValidate is called from method enumerating it, but when modification occurs, the queue gets modified.

Could you provide full stack trace? If this really happens, it's a bug, so we'll fix it.

answered May 24 '10 at 02:26

Alex%20Yakunin's gravatar image

Alex Yakunin
29714412

at System.Collections.Generic.HashSet`1.Enumerator.MoveNext() at Xtensive.Integrity.Validation.ValidationContextBase.Validate() at Xtensive.Storage.Validation.Enforce(Session session) at Xtensive.Storage.Validation.Enforce()

(May 24 '10 at 02:26) ara ara's gravatar image

Yep... That's it. To be fixed.

(May 24 '10 at 02:26) Alex Yakunin Alex%20Yakunin's gravatar image
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!
toggle preview

Subscription:

Once you sign in you will be able to subscribe for any updates here

Tags:

×569

Asked: May 23 '10 at 23:15

Seen: 2,426 times

Last updated: May 23 '10 at 23:15

powered by OSQA