C# 在生产源代码中将实体框架日志设置为调试窗口可以吗?
在生产源代码中使用这一行可以吗?它会产生什么样的性能惩罚?我知道Debug.WriteLine不会发送到使用版本配置构建的程序集C# 在生产源代码中将实体框架日志设置为调试窗口可以吗?,c#,entity-framework,logging,visual-studio-debugging,C#,Entity Framework,Logging,Visual Studio Debugging,在生产源代码中使用这一行可以吗?它会产生什么样的性能惩罚?我知道Debug.WriteLine不会发送到使用版本配置构建的程序集 ddiCatalogEntities.Database.Log = msg => Debug.WriteLine(msg); 在调试模式下运行时,此行应将实体框架日志输出记录到VisualStudio调试控制台 #if DEBUG ddiCatalogEntities.Database.Log = msg => Debug.WriteLine(msg)
ddiCatalogEntities.Database.Log = msg => Debug.WriteLine(msg);
在调试模式下运行时,此行应将实体框架日志输出记录到VisualStudio调试控制台
#if DEBUG
ddiCatalogEntities.Database.Log = msg => Debug.WriteLine(msg);
#endif
您喜欢上面的解决方案吗?调试类的成员用ConditionalAttribute标记,因此如果您使用发行版配置,则不会编译它们。首先,请注意,您不能将普通委托指向具有
ConditionalAttribute
的方法
但是,您使用的是lambda,因此编译正常。但它实际上编译成什么呢
考虑以下代码:
Action<string> print = message => Debug.WriteLine(message);
print("TEST");
Action print=message=>Debug.WriteLine(message);
打印(“测试”);
对于调试生成,此编译为:
Action<string> print = delegate (string message) {
Debug.WriteLine(message);
};
print("TEST");
Action<string> print = delegate (string message) {
};
print("TEST");
Action print=delegate(字符串消息){
Debug.WriteLine(消息);
};
打印(“测试”);
对于发布版本,它编译为:
Action<string> print = delegate (string message) {
Debug.WriteLine(message);
};
print("TEST");
Action<string> print = delegate (string message) {
};
print("TEST");
Action print=delegate(字符串消息){
};
打印(“测试”);
在这两种情况下,都会创建和调用一个委托-因此,在这两种情况下,都会有委托创建和调用的开销(参数被推送到堆栈上),即使发布版本实际上没有做任何事情
因此,对于您的情况,使用#if DEBUG
与否的区别如下:
- 如果使用
,则根本没有开销,并且不会设置#如果调试
属性日志
- 否则,您将需要设置
属性,然后在调用该属性时不执行任何操作Log
Log
属性始终设置为某个值(默认为“不做任何事情”委托)也很好,这样您就不需要在每次引用它之前检查它是否为null
另一方面,使用#if DEBUG
可以更清楚地了解正在发生的事情。lambda和使用ConditionalAttribute
定义的方法的交互方式并不完全明显
所有这些都是一种迂回的说法:权衡利弊,做出自己的选择 我的同事建议使用.NETReflector,或者只是反编译和反编译发布和调试程序集。它证明了@Matthew Watson在这里所说的话。就我个人而言,我会说#如果调试对op的示例更好,仅仅因为如果.Log委托设置为null,那么EF(至少6)将不会经历准备日志语句的开销,它将完全删除日志格式化程序拦截器。如果您向它抛出一个空委托,那么现在您已经让它执行了一系列字符串操作,而这些操作在任何地方都不会被实际写入。