Line of code not working unless stepped through using breakpoint

c# entity-framework entity-framework-6

Question

The only thing I can think of is a race condition but both the calling function and the line of code are synchronous to my knowledge.

/// <summary>
/// Gets the log format string for an info-level log.
/// </summary>
public static string Info<T>(string action, T obj)
{
    var stringBuilder = new StringBuilder(String.Format(
        "Action: {0} \tObject: {1} \tUser: {2} \tJson: ",
        action, typeof(T).Name, User
    ));

    // Set all virtual properties to null. This should stop circular references of navigation properties.
    var virtualProperties = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(x => x.GetSetMethod().IsVirtual && !x.PropertyType.IsPrimitive);
    foreach (var propInfo in virtualProperties)
    {
        propInfo.SetValue(obj, null); // This Line is the culprit.
    }

    GetJsonSerializer().Serialize(obj, stringBuilder);

    return stringBuilder.ToString();
}

The line propInfo.SetValue(obj, null) will execute if I just breakpoint before the loop and step through one-by-one (or just break on that line) however if I don't use a breakpoint it never sets the property(ies) to null. Why is this?

Specific Details:

  • If I don't use a breakpoint it doesn't work.
  • If I place a breakpoint at the top of the foreach and hit f5 it doesn't work.
  • If I place a breakpoint at the top of the foreach and step-through via f10 it does work.
  • If I place a breakpoint on the line of code propInfo.SetValue(obj, null); it does work.
  • A breakpoint after the loop still shows the values as not null.
  • If I change null to 5 (which isn't a valid value) it throws an exception telling my that it's not a valid value.

To clarify, "Doesn't work" means that it doesn't set the property to null.

What I've tried:

  • Restarting Visual Studio (2013)
  • Changing the line of code (Used to be default(T))
  • Project Properties -> Build -> Optimize Code (initially off)

EDIT

It's been narrowed down that EF Navigation properties are the cause of this behavior. The code is running but for some reason the navigation properties refuse to become null. So what about navigation properties are causing this behavior?

1
8
10/14/2015 7:10:26 PM

Accepted Answer

Lazy-Loading

The navigation properties were lazy-loading, so when the serializer looked at them they got overwritten by the original value. So the setting of null was working the whole time but was getting overwritten by the lazy-loading.

Debugging

The reason the debugging appeared the way it did was because I was looking at the value before I executed the SetValue line of code. This caused the navigation property to load the value before executing the line of code resulting in the null value not being overwritten.

Solution

foreach (var propInfo in virtualProperties)
{
    propInfo.GetValue(obj); // Trigger any navigation property to load.
    propInfo.SetValue(obj, null);
}
5
10/14/2015 7:40:52 PM

Popular Answer

I had a VERY similar issue in a Many-to-many EF6 code first setup. In my Web API controller I had been setting an object's navigation property from values set from a DTO. One being passed into my repo, they properties weren't being updated because of the lazy loading, but in debug mode it would work if I stepped near that section of code. I ended up using:

try {
    TheDatabase.Configuration.LazyLoadingEnabled = false;
    ...
    ...
}
finally {
    TheDatabase.Configuration.LazyLoadingEnabled = true;
}

This appears to be working so far.. Since my dbContext is being disposed per controller, I don't think it will be an issue.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow