本文共 7763 字,大约阅读时间需要 25 分钟。
查看LINQ生成SQL语句的几种方法
分类: C#|DOTNET 发布: yaosansi 浏览: 日期: 2008年9月25日
转载请标明出处:
原文:
记录LINQ生成的SQL语句是常用的调试方式,而且能根据需要来优化LINQ生成的SQL语句,更能了深入的了解LINQ.
DataContext的Log属性来将LINQ to SQL生成的SQL语句格式化.
一.控制台程序(Console)
dataContext.Log = Console.Out;
二.利用GetCommand方法
dataContext.GetCommand(query).CommandText;
三.使用LINQPad ()
LINQPad支持C# 3.0 和 Framework 3.5的全部功能:
- LINQ to SQL
- LINQ to Objects
- LINQ to XML
更多介绍请参考的
下载地址:
四.LINQ to SQL Debug Visualizer
ScottGu的LINQ to SQL Debug Visualizer可以在Debug过程中查看SQL语句.
介绍:
下载:
安装方法
1. 关闭 VS2008。
2. 将压缩包中的 SqlServerQueryVisualizer.dll 拷贝到 \Program Files\Microsoft Visual Studio 9.0\Common7\Packages\Debugger\Visualizers。
3. 重启 VS2008 即可。
五.DebuggerWriter工具类
由于Console.Out方法在ASP.NET程序不起作用.
已经创建好了一个这个工具类, 你只要使用这样的语法:
MyDataContext db = new MyDataContext();
db.Log = new DebuggerWriter();
asp.net可以选择将Log信息直接发送到Debug的输出窗口.
源码:
using System; using System.Diagnostics; using System.Globalization; using System.IO; using System.Text; namespace Vandermotten.Diagnostics { /**//// <summary> /// Implements a <see cref="TextWriter"/> for writing information to the debugger log. /// </summary> /// <seealso cref="Debugger.Log"/> public class DebuggerWriter : TextWriter { private bool isOpen; private static UnicodeEncoding encoding; private readonly int level; private readonly string category; /**//// <summary> /// Initializes a new instance of the <see cref="DebuggerWriter"/> class. /// </summary> public DebuggerWriter() : this(0, Debugger.DefaultCategory) { } /**//// <summary> /// Initializes a new instance of the <see cref="DebuggerWriter"/> class with the specified level and category. /// </summary> /// <param name="level">A description of the importance of the messages.</param> /// <param name="category">The category of the messages.</param> public DebuggerWriter(int level, string category) : this(level, category, CultureInfo.CurrentCulture) { } /**//// <summary> /// Initializes a new instance of the <see cref="DebuggerWriter"/> class with the specified level, category and format provider. /// </summary> /// <param name="level">A description of the importance of the messages.</param> /// <param name="category">The category of the messages.</param> /// <param name="formatProvider">An <see cref="IFormatProvider"/> object that controls formatting.</param> public DebuggerWriter(int level, string category, IFormatProvider formatProvider) : base(formatProvider) { this.level = level; this.category = category; this.isOpen = true; } protected override void Dispose(bool disposing) { isOpen = false; base.Dispose(disposing); } public override void Write(char value) { if (!isOpen) { throw new ObjectDisposedException(null); } Debugger.Log(level, category, value.ToString()); } public override void Write(string value) { if (!isOpen) { throw new ObjectDisposedException(null); } if (value != null) { Debugger.Log(level, category, value); } } public override void Write(char[] buffer, int index, int count) { if (!isOpen) { throw new ObjectDisposedException(null); } if (buffer == null || index < 0 || count < 0 || buffer.Length - index < count) { base.Write(buffer, index, count); // delegate throw exception to base class } Debugger.Log(level, category, new string(buffer, index, count)); } public override Encoding Encoding { get { if (encoding == null) { encoding = new UnicodeEncoding(false, false); } return encoding; } } public int Level { get { return level; } } public string Category { get { return category; } } }}
六.将LINQ to SQL生成的SQL语句写入日志文件
DataContext.Log是System.IO.TextWriter类型,所以你可以用以下的方法来做.
StreamWriter sw = new StreamWriter(
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "log.txt"));
dBLinqDataContext.Log = sw;
var query = dataContext.Customers.Single<Customer>(c=>c.CustomerID.Contains("s"))
.Skip(0).Take(10).ToList();
sw.Flush();
sw.Close();
但以上方法有个缺点,就是需要在每个实现的方法中都写这么多代码.使用起来太不方便.参照dataContext.Log = Console.Out的表现形式
由是有了FileLog类.(当然,FileLog类除了此功能还有一些基本的记录日志的方法)
使用时直接dataContext.Log = Yaosansi.IO.FileLog.Out;即可. 默认会在桌面上生成一个名叫UnNameFile.txt的文件.
当然如果你不想使用默认的文件名和路径也可以使用dataContext.Log =new Yaosansi.IO.FileLog("FileName")的方式.
下面是FileLog类的源码:
// 原文: http://www.yaosansi.com/post/1380.html using System; using System.Collections.Generic; using System.Text; using System.IO; namespace Yaosansi.IO { /**//// <summary> /// 文件操作 /// </summary> public class FileLog : TextWriter { 构造函数#region 构造函数 /**//// <summary> /// /// </summary> /// <param name="fileName">文件名[文件路径使用默认路径]</param> public FileLog(string fileName) : this(fileName,string.Empty,false) { } /**//// <summary> /// /// </summary> /// <param name="fileName">文件名</param> /// <param name="filePath">文件路径</param> /// <param name="deleteExistingFile">是否删除已经存在的文件</param> public FileLog(string fileName,string filePath, bool deleteExistingFile):this(fileName,filePath,long.MaxValue) { if (deleteExistingFile) { DeleteFile(); } } /**//// <summary> /// /// </summary> /// <param name="fileName">文件名</param> /// <param name="filePath">文件路径</param> /// <param name="fileSize">文件大小[单位:bytes]超出此大小将自动删除文件(使用longong.MaxValue例外)</param> /// public FileLog(string fileName, string filePath, long fileSize) { if (!string.IsNullOrEmpty(fileName)) { FileName = fileName; } else { FileName = "UnNameFile.txt"; } if (!string.IsNullOrEmpty(filePath)) { FilePath = filePath; } else { FilePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); } FileSize = fileSize; } #endregion 重写TextWriter#region 重写TextWriter public override Encoding Encoding { get { return new UnicodeEncoding(false, false); } } public override void Write(char value) { WriteFile(value.ToString()); } public override void Write(string value) { if (value != null) { WriteFile(value); } } public override void Write(char[] buffer, int index, int count) { if (buffer == null || index < 0 || count < 0 || buffer.Length - index < count) { base.Write(buffer, index, count); } WriteFile(new string(buffer, index, count)); } #endregion 属性#region 属性 /**//// <summary> /// 文件名 /// </summary> public string FileName { set; get; } /**//// <summary> /// 获取文件全名[包含路径] /// </summary> public string FullFileName { get { return FilePath + "\\" + FileName; } } /**//// <summary> /// 定义文件大小 /// </summary> public long FileSize { set; get; } /**//// <summary> /// 文件路径; /// </summary> public string FilePath { set; get; } /**//// <summary> /// FileLog Factory /// </summary> public static FileLog Out { get { return new FileLog(""); } } #endregion 方法#region 方法 /**//// <summary> /// 删除文件 /// </summary> /// <returns></returns> public bool DeleteFile() { bool succeed = false; try { if (File.Exists(FullFileName)) { File.Delete(FullFileName); succeed = true; } } catch { } return succeed; } /**//// <summary> /// 仅记录当前时间及分隔符 /// </summary> public void WirteTime() { string message = "\r\n-------------------------------------------------------\r\n" + "时间:" + DateTime.Now.ToString() + "\r\n" + "-------------------------------------------------------"; WriteFile(message); } /**//// <summary> /// 写文件 /// </summary> /// <param name="Message"></param> public void WriteFile(string Message) { StreamWriter sw = null; try { //如果文件目录不存在,则创建 if (!Directory.Exists(FilePath)) { Directory.CreateDirectory(FilePath); } //超过一定大小自动删除文件 if (FileSize != long.MaxValue) { FileInfo finfo = new FileInfo(FullFileName); if (finfo.Exists && finfo.Length > FileSize) { finfo.Delete(); } } if (!File.Exists(FullFileName)) { sw = File.CreateText(FullFileName); } else { sw = File.AppendText(FullFileName); } sw.WriteLine(Message); sw.Flush(); } catch (Exception ee) { Console.WriteLine("文件没有打开,详细信息如下:" + ee.ToString()); throw (new Exception("文件没有打开,详细信息如下:" + ee.ToString())); } finally { sw.Close(); sw.Dispose(); } } #endregion }} 转载于:https://www.cnblogs.com/baiyu/archive/2012/02/15/2352931.html