0

On previous efforts with old versions of Entity Framework, I'm used to using Eager Loading - so you get your root entity and then gather related entities as required by the use of "Include".

On my current project we've implemented the latest version of EF on a new database, using database-first. Take this class, for example:

public partial class Zone
{
    public Zone()
    {
        this.OverrideCharges = new HashSet<OverrideCharge>();
    }

    public System.Guid RowId { get; set; }
    public string Name { get; set; }

    public virtual ICollection<OverrideCharge> OverrideCharges { get; set; }
}

The OverrideCharges object also has a number of sub-properties underneath it, with related entities under those.

We have two contexts, the actual DB context and a set of DTO contexts. The objects for the latter are mostly copies of the former - the Zone_dto object is pretty much a clone of the original. In both, I have turned off Lazy Loading by using:

    public CContext(): base("BreezeMetaData")
    {
        this.Configuration.LazyLoadingEnabled = false;
    }

    public UDBEntities()
        : base("name=UDBEntities")
    {
        this.Configuration.LazyLoadingEnabled = false;
    }

Now, I query my Zone objects by doing this:

    public List<Zone_dto> GetZones()
    {
        List<Zone> zones = _cilContext.Zones.ToList();
        List<Zone_dto> zone_dtos = new List<Zone_dto>();

        foreach (Zone zn in zones)
        {
            zone_dtos.Add(Mapper.Map<Zone, Zone_dto>(zn));
        }

        return zone_dtos;
    }

So - no includes. And Lazy Loading is disabled. I would expect to get back a list of Zone objects and their direct properties, but not any related entities.

But what I get back are the Zone objects, plus all their OverrideCharges, plus all the related entities to those OverrideCharges and so on, all the way down the tree.

These data objects are not huge, and it's not a massive problem. But I'm frustrated that I don't understand why I'm getting back all this data that I haven't asked for. Can someone explain?

Bob Tway
  • 9,301
  • 17
  • 80
  • 162
  • Are you turning off LazyLoading for the entire lifetime of the context, or just for this operation? Your context could potentially have loaded the data before this operation, and by generating that list, you'll see it all (as the load was done before you turned off lazy loading). – Chris Aug 06 '13 at 10:38
  • It's disabled in the constructor - see the edit – Bob Tway Aug 06 '13 at 10:42

2 Answers2

1

What you're describing is exactly what I'd expect - you seem to have Lazy and Eager Loading backwards.

Lazy loading means that the context won't load everything - it's lazy, because it does less work, and loads only what you ask for specifically. .Include() is needed when there is lazy loading, because you're telling it not to be lazy about the thing you're Include()ing.

Eager loading means that the context will load all the things you might need, before you ask for them, by following links from the item you requested and loading whatever they lead to. With lazy loading turned off, it doesn't need to be told to Include() things because it will load everything by default. Use of .Include() is referred to as eager loading because you're telling it to use eager-loading behaviour for that property; with eager loading on everything by default, you don't need .Include().

Set LazyLoadingEnabled = true; and see what happens.

anaximander
  • 7,083
  • 3
  • 44
  • 62
  • It seems to make absolutely no difference - exactly the same data is returned. Which suggests the problem is somewhere else in the code. No idea where though. – Bob Tway Aug 06 '13 at 11:00
  • Even if you set the relevant properties to `virtual`? – anaximander Aug 06 '13 at 11:02
  • Aha. If I set then to *not* virtual, it only loads the base properties. Right, thanks - can you tweak EF to create models with non-virtual navigation properties? – Bob Tway Aug 06 '13 at 11:13
  • You can use dynamic proxies - basically, EF creates a class that wraps your class and adds change tracking and lazy-load behaviour; I'm fairly sure that works with non-virtual navigation properties but you'd have to test it to be sure. Try adding `this.Configuration.ProxyCreationEnabled = true;` after the line about lazy loading. Check [this MSDN page](http://msdn.microsoft.com/en-us/data/jj592886.aspx) for details. – anaximander Aug 06 '13 at 12:08
0

It may be because of the virtual keyword. A virtual ICollection will be lazy-loaded.

See this SO link.

Community
  • 1
  • 1
Ben Gulapa
  • 1,619
  • 14
  • 10