我们知道,使用LINQPad载入项目组件(EDMX 所在project DLL)后就可以在LINQPad中操作LINQ Query,以达到程式实作前的测试操作,如果项目所使用的数据库是MS SQL Server的话,在LINQPad中可以直接观察EF所产出的SQL Command,但要是专案所使用的资料库是Oracle,那么在LINQPad就无法看到EF所产出的SQL Command,这种情况下就必须要回到Visual Studio中于debug模式下进行EF产出SQL Command的观察了
方法一:使用ObjectQuery's ToTraceString Property
这方式的操作方式相当简单,有两种方式来使用这个方法
在VS Debug 模式下:
接着进入侦错模式,执行到第29行过后,将滑鼠游标移到「traceString」上面就可以看到输出的SQL Command,
或是滑鼠游标移到「traceString」上面时,去点选IntelliSence所显示的「放大镜图示」
文字视觉化显示
在LINQPad 环境下:
Language 选择: C# Statements, 使用相同的代码, 输出traceString 值即可: traceString.Dump();
复制产出的SQL Command并且贴到可以执行SQL Command的环境下执行,例如 SQL Developer, SQL Navigator,Navicat 等等
有些人是不喜欢在侦错时才能去观察EF产出的SQL Command,那如果系统已经上线或是非侦测模式下,那不就不能观察产出的SQL吗?
而使用LINQPad做LINQ Query Expression的操作测试,就无法即时产出Oracle的SQL Command……
因为Oracle并没有MS SQL Server那样有提供SQL Profiler的工具(MS SQL Server完整版才有, Express版没有),虽然有相关的工具可以Profiler Oralce的SQL Command,但好用的要钱,不用钱的也不是很好用。
在LINQPad中去执行LINQ Query Expression:
接着在Sql Developer的Query中去执行以下的SQL Command:
select module,first_load_time ,sql_text
from v$sql
where
TO_DATE(first_load_time, 'yyyy-mm-dd hh24:mi:ss' ) <= SYSDATE
order by first_load_time desc;
执行结果:
可以于查询结果中看到第一笔资料,「MODULE」栏位是「LINQPad.exe」而其执行的SQL Command就记录在「SQL_TEXT」栏位中
如果是在Visual Studio的侦测模式下执行,在Profiler的查询结果如下:
如果说,你的程式开发Web 伺服器是使用Visual Studio 所预设的,或是开发专案的网站已经附加到IIS伺服器的网站,我必须说…有时还真的找不到MODULE 为「WebServer .exe」与MODULE 为「w3wp.exe」的资料……
MS SQL Server
Oracle
观察ADO.NET Entity Framework 5.0 所产生的SQL Command
如果专案使佣MS SQL Server而开发环境只有安装MS SQL Server Express Management Studio,想要有SQL Profiler的功能,建议可以使用「AnjLab Sql Profiler」,这是一套免费的工具软体,同样提供与MS SQL Server SQL Profiler一样的功能。
如前面所说的,Oracle资料库如同比较少像MS SQL Server SQL Profiler同样功能的监测工具,「Statement Tracer for Oracle」
以上论述的是以使用ADO.NET Entity Framework 4.0 以及.NET 4.0 为背景,不过换成ADO.NET Entity Framework 5.0 与.NET 4.5 的使用情境下就会有所不同了,那两篇文章内所说的方法就行不通,所以就必须要换另外的方式来完成需求。
Entity Framework 4.0 可以对ObjectQuert<T>使用ToTraceString()来取得,但是当使用了EF 5以及.NET 4.5之后却无法使用ToTraceString()来取得SQL Command了
这是因为我们所处理的资料已经不再是ObjectQuery<T> 而是DbQuery<T>,所以无法使用ToTraceString() 方法
解决办法:直接使用DbQuery<T>.ToString() , 就可给出对应SQL Command