I'm working on a CRM-style MVC web app, which has the following (simplified) schema:
Contacts Table
- ContactId
- Forename
- Surname
- Etc.
Tags Table
- TagId
- Value
ContactTags Table
- ContactId
- TagId
I've then gene开发者_开发知识库rated POCO objects from the *.edmx file, interacting with a DbContext-based entities context, hiding the ContactTags table so that the relationship between Contact and Tag entities is modelled as a many-to-many association. I've then restricted access to the raw Contact.Tags navigation property, setting it to be internal rather than public, and exposed a ReadOnlyCollection that can be used outside the Domain layer for displaying tags, but restricting data operations on the collection to a Contact.EditTags() method.
Upon writing UI code to display the list of tags on a contact, I found that the Tags navigation property isn't being lazy-loaded. After scratching my head and googling about a bit, I found another question at EF CTP4 lazy loading not playing ball which matched my problem. The author of the question found that when he changed the internal property to be public, it started working, and sure enough this is what happened for me too - I've changed the Tags navigation property to be public, and it's now working.
I'm uncomfortable with this from an object modelling/data encapsulation point of view, since the UI shouldn't be given access to the raw Tags collection which would enable controller code to call Tags.Add(), Tags.Remove, etc.
Does anyone know if this is a bug, or a deliberate design decision by the EF team? Is it possible to get an internal navigation property to be lazy-loaded? I know we could eager-load, but we'd like to avoid that if at all possible.
Lazy loading on POCOs needs creation of POCO proxies. Proxies are only created when the model classes fulfill certain requirements. One of these requirements for proxies which enable lazy loading is this one:
Each navigation property must be declared as public, virtual (Overridable in Visual Basic), and not sealed (NotOverridable in Visual Basic) get accessor.
Quote from here: http://msdn.microsoft.com/en-us/library/dd468057.aspx
精彩评论