C# 除非使用断点逐步执行,否则代码行不工作

C# 除非使用断点逐步执行,否则代码行不工作,c#,entity-framework,entity-framework-6,C#,Entity Framework,Entity Framework 6,我唯一能想到的是竞争条件,但调用函数和代码行都是同步的 /// <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( "Ac

我唯一能想到的是竞争条件,但调用函数和代码行都是同步的

/// <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();
}
//
///获取信息级别日志的日志格式字符串。
/// 
公共静态字符串信息(字符串操作,T obj)
{
var stringBuilder=新的stringBuilder(String.Format(
“操作:{0}\t对象:{1}\t用户:{2}\tJson:”,
操作,类型(T).名称,用户
));
//将所有虚拟属性设置为null。这将停止导航属性的循环引用。
var virtualProperties=typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public)。其中(x=>x.GetSetMethod().IsVirtual&!x.PropertyType.IsPrimitive);
foreach(虚拟财产中的var propInfo)
{
SetValue(obj,null);//这一行是罪魁祸首。
}
GetJsonSerializer().Serialize(obj,stringBuilder);
返回stringBuilder.ToString();
}
如果我只在循环前设置断点并逐个执行(或在该行上中断),那么将执行行
propInfo.SetValue(obj,null)
,但是如果我不使用断点,它将不会将属性设置为null。为什么会这样

具体细节

  • 如果我不使用断点,它就不起作用
  • 如果我在foreach的顶部放置一个断点并点击f5,它将不起作用
  • 如果我在foreach的顶部放置一个断点,并通过f10进行单步操作,它就可以工作了
  • 如果我在代码
    propInfo.SetValue(obj,null)的行上放置一个断点它确实有效
  • 循环后的断点仍将值显示为NOTNULL
  • 如果我将
    null
    更改为
    5
    (这不是一个有效值),它会抛出一个异常,告诉我它不是一个有效值
为了澄清,“不工作”意味着它不会将属性设置为null

我所尝试的:

  • 重新启动Visual Studio(2013)
  • 更改代码行(以前是
    default(T)
  • 项目属性->构建->优化代码(最初关闭)
编辑


据了解,EF导航属性是导致这种行为的原因。代码正在运行,但由于某些原因,导航属性拒绝变为null。那么导致这种行为的导航属性是什么呢?

延迟加载

导航属性是延迟加载的,因此当序列化程序查看它们时,它们会被原始值覆盖。所以null的设置一直在工作,但是被延迟加载覆盖了

调试

调试之所以出现这种情况,是因为我在执行SetValue行代码之前查看了该值。这导致navigation属性在执行代码行之前加载该值,从而导致空值不会被覆盖

解决方案

foreach (var propInfo in virtualProperties)
{
    propInfo.GetValue(obj); // Trigger any navigation property to load.
    propInfo.SetValue(obj, null);
}

在多对多EF6代码初始设置中,我遇到了一个非常类似的问题。在我的WebAPI控制器中,我一直在根据DTO设置的值设置对象的导航属性。其中一个被传递到我的repo中,由于延迟加载,它们的属性没有被更新,但是在调试模式下,如果我靠近代码的那一部分,它就会工作。我最终使用了:

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

到目前为止,这似乎是可行的。。因为我的dbContext是按控制器处理的,所以我认为这不会是一个问题。

如果在您将其传递给obj之前发生了什么事情,请告诉obj?我将提交它进行编辑。它通过EF保存到数据库中。然后我将其传递给此文件以进行序列化和记录。在这种情况下,我无法想象这之前会有什么影响,但我想一切都是可能的。在此函数之后,log4net将日志条目保存到数据库中。如果尝试非EF
T
类型,会发生什么情况?可能是实体框架不“接受”属性更改,我们可以确定原因。好的,最后的“细节”让我认为问题与我在实体框架中设置的导航属性有关。但我不确定为什么会出现这种行为。是的,这是EF导航属性的事情。非EF虚拟非原语被设置为null。奇怪的是,在typeof(T)的末尾添加.All()或.ToList()选择器。GetProperties(…)会强制集合枚举并加载所有项吗?
。添加到
typeof(T)的.GetProperties()
不会强制加载。这是因为它位于properties集合上,而不是属性本身。我试着证实我的怀疑。