Как получить запрос TSQL из LINQ DataContext.SubmitChanges()
Я использую Linq для SQL. У меня есть DataContext, против которого я.SubmitChanges()'. Произошла ошибка при вставке поля идентификатора, и я хотел бы увидеть запрос, который он использует для вставки этого поля идентификатора.
Я не вижу сам запрос в быстрых часах; где я могу найти его в отладчике?
7 ответов
На самом деле есть очень простой ответ на ваш вопрос
Просто вставьте это в окно с часами
((System.Data.Objects.ObjectQuery)myLinqQueryVar).ToTraceString()
Многие люди пишут свой собственный "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.
В дополнение к ответу Портмана, если вы консольное приложение, это так просто:
myDataContext.Log = Console.Out;
Или вы можете использовать что-то вроде Linq2SQL Profiler, который является довольно хорошим инструментом и фактически подходящим инструментом для работы:
Linq to SQL Profiler - визуальный отладчик в реальном времени для Linq to SQL
Запустите SQL Profiler, если он у вас есть. Он покажет весь трафик к вашей базе данных, включая текст команды SQL.
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();
Я согласен, что Linq to SQL Profiler - правильный инструмент для этой работы. Но если вы не хотите тратить деньги или просто хотите сделать что-то простое, мне нравится подход DebugTextWriter.
Прочитав этот вопрос, я отправился на поиски чего-то более крепкого. Оказывается, Damien Guard также написал очень хорошую статью о том, как создавать разных авторов, чтобы иметь дело с разными вещами, такими как вывод в память, отладка, файл, несколько мест назначения или даже использование простых делегатов.
Я использовал пару его идей и написал 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);
}
}
}
}
Вы можете добавить столько действий, сколько хотите. В этом примере выполняется запись в файл журнала и консоль в Visual Studio через Debug.Write:
// 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);
}
}
}
Вот подробное описание: http://debugmode.net/2011/06/26/logging-in-linq-to-sql/