简体   繁体   中英

Problem with Entity Framework and Lazy Loading

I am using Entity Framework 4 and am having a few problems with lazy loading. I have 3 entities and are each contained in one another. CarSetup will contain a Car entity who will contain an Event entity. They are all being lazy loaded.

I have created a simplistic unit test to reproduce the problem.

CarSetup carSetup = carSetupContext.CreateObject<CarSetup>();
Car car = Load("car1");
carSetup.Car = car;

I get a crash when i assign the car to the carsetup object. It actually crashes in the Equals method of the Car entity.

public override bool Equals(object obj)
{
    if(obj == null)
    {
        return false;
    }

    return this.Event.Equals(((Car)obj).Event);
}

If i quickwatch the entity before the equals method gets called, all sub entities get loaded and the problem does not occur.

When i assign the existing car to the car setup, the framework loads all existing CarSetups for that car and calls my "Equals" method with them. However, since lazy loading is enabled, the Event in the Car is null which is normal. When it tries to access the Event property, NO loading happens and it crashes. I have checked the "this" property in the equals method and it is of type "System.Data.Entity.DynamicProxies.Car". I also checked and the EventId Guid is correctly set in the car entity.

Anyone have any idea as to what is happening?

EDIT: After doing a bit more testing, if I call my equals method manualy:

car.Equals(car);

Everything works perfectly. It only happens when the Entity Framework decides to load relationships and automatically calls the Equals method.

Thanks

It seems that the Event isn't being loaded. From memory I would have done something like this to ensure that the Events are loaded with the Cars:

context.Cars.Include("Events");

You're using a syntax that I'm not familiar with, but look into the Include operator.

You seem to use POCO objects with enabled DynamicProxies in your object context, right? It might be possible that by casting obj to Car in your Equals override you cast to your POCO class and not to System.Data.Entity.DynamicProxies.Car which is dynamically derived from Car . With that cast you are effectively stripping off the ability of obj (which is probably also of type System.Data.Entity.DynamicProxies.Car like this ) to lazily load navigation properties. (Because it's the DynamicProxy which enables lazy loading of POCO entities.)

Now the problem is that you can't cast to System.Data.Entity.DynamicProxies.Car instead of Car since this type doesn't exist at compile time and is only dynamically generated at runtime.

But if you are using C# 4.0 (Visual Studio 2010) you could try to use dynamic typing with the new dynamic keyword. Your Equals override would look like this:

public override bool Equals(object obj)
{
    if(obj == null)
    {
        return false;
    }

    dynamic o = obj;

    return this.Event.Equals(o.Event);
}

(This all is a shot into the dark and I didn't test anything. But it might be worth a try.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM