您的位置:首页 > 数据库

查看LINQ生成SQL语句的几种方法

2017-11-03 08:25 453 查看
记录LINQ生成的SQL语句是常用的调试方式,而且能根据需要来优化LINQ生成的SQL语句,更能了深入的了解LINQ.

DataContext的Log属性来将LINQtoSQL生成的SQL语句格式化.

一.控制台程序(Console)
dataContext.Log=Console.Out;


二.利用GetCommand方法

dataContext.GetCommand(query).CommandText;

三.使用LINQPad(官方网站)

LINQPad支持C#3.0和Framework3.5的全部功能:

LINQtoSQL
LINQtoObjects
LINQtoXML



更多介绍请参考李永京的学习LINQ工具:LINQPad

下载地址:http://www.albahari.com/LINQPad.exe

四.LINQtoSQLDebugVisualizer

ScottGu的LINQtoSQLDebugVisualizer可以在Debug过程中查看SQL语句.

介绍:http://weblogs.asp.net/scottgu/archive/2007/07/31/linq-to-sql-debug-visualizer.aspx

下载:http://www.scottgu.com/blogposts/linqquery/SqlServerQueryVisualizer.zip

安装方法

1.关闭VS2008。

2.将压缩包中的SqlServerQueryVisualizer.dll拷贝到\ProgramFiles\MicrosoftVisualStudio9.0\Common7\Packages\Debugger\Visualizers。

3.重启VS2008即可。

五.DebuggerWriter工具类

由于Console.Out方法在ASP.NET程序不起作用.

KrisVandermotten已经创建好了一个这个工具类,你只要使用这样的语法:

MyDataContextdb=newMyDataContext();

db.Log=newDebuggerWriter();



asp.net可以选择将Log信息直接发送到Debug的输出窗口.

源码:



usingSystem;


usingSystem.Diagnostics;


usingSystem.Globalization;


usingSystem.IO;


usingSystem.Text;




namespaceVandermotten.Diagnostics


{


///<summary>


///Implementsa<seecref="TextWriter"/>forwritinginformationtothedebuggerlog.


///</summary>


///<seealsocref="Debugger.Log"/>


publicclassDebuggerWriter:TextWriter


{


privateboolisOpen;


privatestaticUnicodeEncodingencoding;


privatereadonlyintlevel;


privatereadonlystringcategory;




///<summary>


///Initializesanewinstanceofthe<seecref="DebuggerWriter"/>class.


///</summary>


publicDebuggerWriter()


:this(0,Debugger.DefaultCategory)


{


}




///<summary>


///Initializesanewinstanceofthe<seecref="DebuggerWriter"/>classwiththespecifiedlevelandcategory.


///</summary>


///<paramname="level">Adescriptionoftheimportanceofthemessages.</param>


///<paramname="category">Thecategoryofthemessages.</param>


publicDebuggerWriter(intlevel,stringcategory)


:this(level,category,CultureInfo.CurrentCulture)


{


}




///<summary>


///Initializesanewinstanceofthe<seecref="DebuggerWriter"/>classwiththespecifiedlevel,categoryandformatprovider.


///</summary>


///<paramname="level">Adescriptionoftheimportanceofthemessages.</param>


///<paramname="category">Thecategoryofthemessages.</param>


///<paramname="formatProvider">An<seecref="IFormatProvider"/>objectthatcontrolsformatting.</param>


publicDebuggerWriter(intlevel,stringcategory,IFormatProviderformatProvider)


:base(formatProvider)


{


this.level=level;


this.category=category;


this.isOpen=true;


}




protectedoverridevoidDispose(booldisposing)


{


isOpen=false;


base.Dispose(disposing);


}




publicoverridevoidWrite(charvalue)


{


if(!isOpen)


{


thrownewObjectDisposedException(null);


}


Debugger.Log(level,category,value.ToString());


}




publicoverridevoidWrite(stringvalue)


{


if(!isOpen)


{


thrownewObjectDisposedException(null);


}


if(value!=null)


{


Debugger.Log(level,category,value);


}


}




publicoverridevoidWrite(char[]buffer,intindex,intcount)


{


if(!isOpen)


{


thrownewObjectDisposedException(null);


}


if(buffer==null||index<0||count<0||buffer.Length-index<count)


{


base.Write(buffer,index,count);//delegatethrowexceptiontobaseclass


}


Debugger.Log(level,category,newstring(buffer,index,count));


}




publicoverrideEncodingEncoding


{


get


{


if(encoding==null)


{


encoding=newUnicodeEncoding(false,false);


}


returnencoding;


}


}




publicintLevel


{


get{returnlevel;}


}




publicstringCategory


{


get{returncategory;}


}


}


}





六.将LINQtoSQL生成的SQL语句写入日志文件

DataContext.Log是System.IO.TextWriter类型,所以你可以用以下的方法来做.

StreamWritersw=newStreamWriter(
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),"log.txt"));

dBLinqDataContext.Log=sw;

varquery=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=newYaosansi.IO.FileLog("FileName")的方式.

下面是FileLog类的源码:


//原文:http://www.yaosansi.com/post/1380.html


usingSystem;


usingSystem.Collections.Generic;


usingSystem.Text;


usingSystem.IO;




namespaceYaosansi.IO


{


///<summary>


///文件操作


///</summary>


publicclassFileLog:TextWriter


{


#region构造函数






///<summary>


///


///</summary>


///<paramname="fileName">文件名[文件路径使用默认路径]</param>


publicFileLog(stringfileName)


:this(fileName,string.Empty,false)


{


}




///<summary>


///


///</summary>


///<paramname="fileName">文件名</param>


///<paramname="filePath">文件路径</param>


///<paramname="deleteExistingFile">是否删除已经存在的文件</param>


publicFileLog(stringfileName,stringfilePath,booldeleteExistingFile):this(fileName,filePath,long.MaxValue)


{


if(deleteExistingFile)


{


DeleteFile();


}


}




///<summary>


///


///</summary>


///<paramname="fileName">文件名</param>


///<paramname="filePath">文件路径</param>


///<paramname="fileSize">文件大小[单位:bytes]超出此大小将自动删除文件(使用longong.MaxValue例外)</param>


///


publicFileLog(stringfileName,stringfilePath,longfileSize)


{


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




#region重写TextWriter






publicoverrideEncodingEncoding


{


get


{


returnnewUnicodeEncoding(false,false);


}


}






publicoverridevoidWrite(charvalue)


{


WriteFile(value.ToString());


}




publicoverridevoidWrite(stringvalue)


{


if(value!=null)


{


WriteFile(value);


}


}




publicoverridevoidWrite(char[]buffer,intindex,intcount)


{


if(buffer==null||index<0||count<0||buffer.Length-index<count)


{


base.Write(buffer,index,count);


}


WriteFile(newstring(buffer,index,count));


}




#endregion




#region属性


///<summary>


///文件名


///</summary>


publicstringFileName{set;get;}




///<summary>


///获取文件全名[包含路径]


///</summary>


publicstringFullFileName


{


get


{


returnFilePath+"\\"+FileName;


}


}




///<summary>


///定义文件大小


///</summary>




publiclongFileSize{set;get;}




///<summary>


///文件路径;


///</summary>




publicstringFilePath


{


set;


get;


}




///<summary>


///FileLogFactory


///</summary>


publicstaticFileLogOut


{


get


{


returnnewFileLog("");


}


}




#endregion




#region方法


///<summary>


///删除文件


///</summary>


///<returns></returns>


publicboolDeleteFile()


{


boolsucceed=false;


try


{


if(File.Exists(FullFileName))


{


File.Delete(FullFileName);


succeed=true;


}


}


catch{}


returnsucceed;


}






///<summary>


///仅记录当前时间及分隔符


///</summary>


publicvoidWirteTime()


{


stringmessage="\r\n-------------------------------------------------------\r\n"+


"时间:"+DateTime.Now.ToString()+"\r\n"+


"-------------------------------------------------------";


WriteFile(message);


}




///<summary>


///写文件


///</summary>


///<paramname="Message"></param>


publicvoidWriteFile(stringMessage)


{


StreamWritersw=null;


try


{


//如果文件目录不存在,则创建


if(!Directory.Exists(FilePath))


{


Directory.CreateDirectory(FilePath);


}


//超过一定大小自动删除文件


if(FileSize!=long.MaxValue)


{


FileInfofinfo=newFileInfo(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(Exceptionee)


{


Console.WriteLine("文件没有打开,详细信息如下:"+ee.ToString());


throw(newException("文件没有打开,详细信息如下:"+ee.ToString()));


}


finally


{


sw.Close();


sw.Dispose();


}


}


#endregion






}


}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: