Domanda

I want to build up an object graph using Entity Framework 4.2.

Right now, I have POCO entities, using ICollection for navigation properties. I want to avoid using EntityCollection or anything EF-specific.

I want to avoid massive joins caused by using Include excessively. Given an object, I want to populate its navigation properties, resulting in a separate database query.

Is there a way to populate an ICollection directly? Right now, I am working around the problem, but it is really painful.

// grab the user, brand users and brands
User user = entities.Users
                    .Include(item => item.BrandUsers.Select(brandUser => brandUser.Brand))
                    .Where(item => item.Name == userName)
                    .SingleOrDefault();
// grab the pending share grants and brands
entities.Users
        .Include(item => item.ToShareGrants.Select(shareGrant => shareGrant.Brand))
        .Where(item => item.Id == user.Id)
        .Load();
return user;

One thing I don't like about this approach is that I am re-querying the top-level object. If I don't do this, the navigation property isn't populated (left NULL) when there are no objects returned. For instance, the following code only works if results are returned:

entities.ShareGrants
        .Include(item => item.Brand)
        .Where(item => item.ToUserId == user.Id)
        .Load();

I was curious if there was just a method I wasn't aware of in entity framework for building these types of relationships. If anyone knows an easy approach to filling out navigation properties in steps, I'd appreciate a code sample.

È stato utile?

Soluzione 3

The short answer to this question is that EF4 did not directly support the functionality I wanted. In order to prevent a massive join and break the results out across multiple calls to the database, the top-most entity must be downloaded from the database again. This means the left-most columns in the result set will be the columns of that entity repeated for each record.

Altri suggerimenti

Try turn off lazy loading for your current query, you may just put this in a using block

entities.ContextOptions.LazyLoadingEnabled = false;

Your question is not very clear. Why not use multiple Includes in the same query

User user = entities.Users
      .Include(item => item.BrandUsers.Select(brandUser => brandUser.Brand))
      .Include(item => item.ToShareGrants.Select(shareGrant => shareGrant.Brand))
      .Where(item => item.Name == userName)
      .SingleOrDefault();
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top