-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rich collection support: Dictionary, Lookup, HashSet, etc. #2919
Comments
During materialization, EF fixes up the navigation collections using standard interface properties e.g. ICollection<T>.Add. As mentioned in a comment in #12675 this is not very satisfactory because the ordering of elements is not preserved during a materialization -- a point that obviously only surfaces for ordered collections. Another way to state this is that the user would like to have Add with the normal semantics of "add at end" while redirecting EF to "add in sorted position" In my experience there are other reasons why the application code may need different collection behavior than that which should be used during materialization. An example is the application code may need to lock an object (such as a DbContext or other object) when writing to the collection, while this locking may not be appropriate for EF materialization. Currently the only work-around for this, to my knowledge, is to have ICollection<T>.Add do something that is inconsistant with the other members of the collection and/or inconsistent with the normal definition of Add. Based on this experience, I suggest that some thought be given to the current design in which EF uses the same interface to add entities during materialization as is used to expose the navigation in the entity. There is an analogy with the property access mode: there is a way to cause materialization to use direct field access, which is different from the way that the property is exposed in the entity class for use in the application. It might make sense to define a separate interface, INavigationCollection<T> with an Add method. A type derived from ICollection<T> would still be used to declare the navigation property, but if the instance object also implements INavigationCollection<T> then the INavigationCollection<T> interface would be used during EF operations such as materialization. This would cleanly solve the issue of separating EF's use and application code's use of the collection. |
A further example on the challenges of locking and EF's use of collections. If the entity design requires locking the navigation collection then, in addition to the materialization/Add conflict noted above, a conflict occurs between locked enumeration and EF's use of the collection when entities are added to the context. When an entity is added to the context, EF will access the collection enumerator in order to patch up entity relationships. However, this may need to occur when the caller already is holding the lock for other reasons. These situations can be difficult to work around because the two alternatives -- either obtain the entity lock in the enumerator, or don't -- are unsatisfactory in many cases. The INavigationCollection approach suggested earlier would address this example as well. |
Please, somebody save me from ordering my child navigation properties after DB retrieval. |
This is the navigation counterpart to #2968 |
Based on feedback at #246 (comment).
The text was updated successfully, but these errors were encountered: