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
- 重新启动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集合上,而不是属性本身。我试着证实我的怀疑。