【问题标题】:How to get the TSQL Query from LINQ DataContext.SubmitChanges()如何从 LINQ DataContext.SubmitChanges() 获取 TSQL 查询
【发布时间】:2010-10-12 20:01:45
【问题描述】:

我正在使用 Linq to SQL。我有一个 DataContext,我正在针对它 .SubmitChanges()'ing。插入标识字段时出错,我想查看它用于插入此标识字段的查询。

我没有在快速监视中看到查询本身;在调试器中哪里可以找到它?

【问题讨论】:

  • 您还可以配置数据上下文以将查询输出到文件中。

标签: c# linq linq-to-sql datacontext submitchanges


【解决方案1】:

很多人一直在编写自己的“DebugWriter”并像这样附加它:

// Add this class somewhere in your project...
class DebugTextWriter : System.IO.TextWriter {
   public override void Write(char[] buffer, int index, int count) {
       System.Diagnostics.Debug.Write(new String(buffer, index, count));
   }

   public override void Write(string value) {
       System.Diagnostics.Debug.Write(value);
   }

   public override Encoding Encoding {
       get { return System.Text.Encoding.Default; }
   }
}

// Then attach it to the Log property of your DataContext...
myDataContext.Log = new DebugTextWriter()

这会将 Linq-to-Sql 正在执行的所有操作输出到 Visual Studio 的调试窗口中。

【讨论】:

    【解决方案2】:

    除了Portman's answer,如果你是一个控制台应用程序,它就像这样简单:

    myDataContext.Log = Console.Out;
    

    或者您可以使用 Linq2SQL Profiler 之类的工具,这是一个相当出色的工具,实际上是适合这项工作的工具:

    Linq to SQL Profiler - Real-time visual debugger for Linq to SQL

    【讨论】:

      【解决方案3】:

      其实你的问题有一个非常简单的答案

      只需将其粘贴到您的监视窗口中

      ((System.Data.Objects.ObjectQuery)myLinqQueryVar).ToTraceString()
      

      【讨论】:

      • 不幸的是,这并不总是有效。例如,您的查询有一个 groupby...
      • 答案取决于 4.1 版中的很多实体框架,您拥有实现 context.Log 的 dbcontext,因此您可以使用下面看到的解决方案,但在此之前,如果您从 objectcontext 继承上下文与上面的解决方案有关,只是不幸的是它并不总是可用
      • 答案是根据最初提出的问题
      【解决方案4】:

      如果有,请运行 SQL Profiler。它将显示到您的数据库的所有流量,包括 SQL 命令文本。

      【讨论】:

      • SQL Profiler 也很方便,还有其他原因,例如:查看代码对数据库的负载。
      【解决方案5】:
      FooDataContext dc = new FooDataContext();
      
      StringBuilder sb = new StringBuilder();
      dc.Log = new StringWriter(sb);
      
      var result=from r in dc.Tables select d;
      
      .....
      string query=sb.ToString();
      

      【讨论】:

        【解决方案6】:

        我同意 Linq to SQL Profiler 是适合这项工作的工具。但是如果你不想花钱或者只需要做一些简单的事情,我喜欢 DebugTextWriter 方法。

        读完这个问题后,我开始寻找更强大的东西。事实证明,Damien Guard 还 wrote a very nice article 关于构建不同的编写器来处理不同的事情,例如输出到内存、调试、文件、多个目标,甚至使用简单的委托。

        我最终使用了他的一些想法并编写了一个可以处理多个委托的 ActionTextWriter,我想我会在这里分享它:

        using System;
        using System.Collections.Generic;
        using System.IO;
        using System.Text;
        
        namespace Writers
        {
            public class ActionTextWriter : TextWriter
            {
                protected readonly List<Action<string>> Actions = new List<Action<string>>();
        
                public ActionTextWriter(Action<string> action)
                {
                    Actions.Add(action);
                }
        
                public ActionTextWriter(IEnumerable<Action<string>> actions)
                {
                    Actions.AddRange(actions);
                }
        
                public ActionTextWriter(params Action<string>[] actions)
                {
                    Actions.AddRange(actions);
                }
        
                public override Encoding Encoding
                {
                    get { return Encoding.Default; }
                }
        
                public override void Write(char[] buffer, int index, int count)
                {
                    Write(new string(buffer, index, count));
                }
        
                public override void Write(char value)
                {
                    Write(value.ToString());
                }
        
                public override void Write(string value)
                {
                    if (value == null)
                    {
                        return;
                    }
        
                    foreach (var action in Actions)
                    {
                        action.Invoke(value);
                    }
                }
            }
        }
        

        您可以添加任意数量的操作。此示例通过 Debug.Write 写入日志文件和 Visual Studio 中的控制台:

        // Create data context
        var fooDc = new FooDataContext();
        
        // Create writer for log file.
        var sw = new StreamWriter(@"C:\DataContext.log") {AutoFlush = true};
        
        // Create write actions.
        Action<string> writeToDebug = s => Debug.Write(s);
        Action<string> writeToLog = s => sw.Write(s);
        
        // Wire up log writers.
        fooDc.Log = new ActionTextWriter(writeToDebug, writeToLog);
        

        当然,如果您想制作更简单的即用型,您可以随时扩展 ActionTextWriter...编写通用方法并重用,对吗?

        using System.Diagnostics;
        using System.IO;
        
        namespace Writers
        {
            public class TraceTextWriter : ActionTextWriter
            {
                public TraceTextWriter()
                {
                    Actions.Add(s => Trace.Write(s));
                }
            }
        
            public class FileTextWriter : ActionTextWriter
            {
                public FileTextWriter(string path, bool append = false)
                {
                    var sw = new StreamWriter(path, append) {AutoFlush = true};
                    Actions.Add(sw.Write);
                }
            }
        }
        

        【讨论】:

          【解决方案7】:

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-04-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-12-31
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多