是否可以将实体框架日志记录设置为生产源代码中的调试窗口

本文关键字:源代码 窗口 调试 设置 实体 框架 记录 日志 是否 | 更新日期: 2023-09-27 18:18:44

生产源代码中有这一行可以吗?它会产生什么样的绩效惩罚?我知道 Debug.WriteLine 不会发送到使用发布配置构建的程序集。

ddiCatalogEntities.Database.Log = msg => Debug.WriteLine(msg);

此行应在调试模式下运行时将实体框架日志输出记录到 Visual Studio 调试控制台。

#if DEBUG 
ddiCatalogEntities.Database.Log = msg => Debug.WriteLine(msg);
#endif

您更喜欢上面的解决方案吗?

是否可以将实体框架日志记录设置为生产源代码中的调试窗口

首先,请注意,您不能将普通委托指向带有 ConditionalAttribute 的方法。

但是,您使用的是 lambda,因此编译正常。但它实际上编译成什么?

请考虑以下代码:

Action<string> print = message => Debug.WriteLine(message);
print("TEST");

对于调试版本,这将编译为:

Action<string> print = delegate (string message) {
    Debug.WriteLine(message);
};
print("TEST");

对于发布版本,它编译为:

Action<string> print = delegate (string message) {
};
print("TEST");

在这两种情况下,都会创建和调用委托 - 因此在这两种情况下,您都将有委托创建和调用的开销(参数在堆栈上推送(,即使发布版本实际上没有做任何事情。

因此,对于您的情况,是否使用 #if DEBUG 之间的区别如下:

  • 如果使用#if DEBUG则根本没有开销,并且不会设置 Log 属性。
  • 否则,您将产生设置 Log 属性的开销,然后在调用它时不执行任何操作。

在许多情况下,开销非常小,以至于您不介意 - 而且确保 Log 属性始终设置为某些内容(默认为"不执行任何操作"委托(也非常好,因此您无需在每次引用它之前检查它与 null

另一方面,使用#if DEBUG可以更清楚地了解正在发生的事情。lambda 和用 ConditionalAttribute 定义的方法交互的方式并不完全明显!

所有这些都是一种迂回的说法:权衡利弊,做出自己的选择。 ;)

Debug 类的成员使用 ConditionalAttribute 进行标记,因此如果使用 Release 配置,则不会编译它们。