是否可以从LINQ查询中提取sql语句?
说,我有这个LINQ表达式。
string[] names =
new string[] { "Jon Skeet", "Marc Gravell", "tvanfosson",
"cletus", "Greg Hewgill", "JaredPar" };
var results = from name in names
where name.StartsWith("J")
select name;
alt text http://ruchitsurati.net/files/linq-debugging.png
在此语句之后,'results'仅保留LINQ表达式而不是由于延迟执行LINQ查询而导致的结果。
我可以从'结果'中提取或生成LINQ查询 从中准备一个有效的SQL语句 查询存储在'LINQ'中?
这是我的目标:
我们已经编写了自己的ORM。我们每次需要进行数据库操作时都必须编写查询。现在我们需要在DAL摆脱它。我们希望在代码中编写LINQ表达式,它将针对我的ORM生成SQL语句,我们将在数据库上执行此SQL。
我是否会编写我的自定义Linq提供商来做我需要的工作?
答案 0 :(得分:22)
编辑:等等,你在谈论LINQ to Objects?不,这是不可能的 1 。无法将LINQ to Object查询的表达式树转换为表示查询某个数据库的表达式树。
编辑:不要写你自己的ORM。这个问题有成熟的解决方案。你试图再次解决这个问题就是在浪费价值。如果您要使用自己的ORM,将表达式转换为SQL语句,是的,您必须编写自己的提供程序。这是MSDN上的walkthrough。
但严重的是,不要写自己的ORM。五年前,NHibernate和LINQ to SQL出现并成熟,很好。但是不是现在。没办法。
本回答的其余部分假设您询问LINQ to SQL。
我知道有两种方式。
首先:
将DataContext.Log
属性设置为Console.Out
(或您选择的其他System.IO.TextWriter
):
var db = new MyDataContext();
db.Log = Console.Out;
这将在执行时将SQL语句打印到控制台。有关此功能的更多信息,请参阅MSDN。在其他地方有examples TextWriter
个,可以将输出发送到调试器输出窗口。
第二
使用Scott Guthrie的LINQ to SQL Debug Visualizer。这允许您通过Visual Studio中的调试器查看SQL语句。此选项的优点是您可以在不执行查询的情况下查看SQL语句。您甚至可以执行查询并在可视化工具中查看结果。
1 :也许并非不可能,但肯定非常难。
答案 1 :(得分:15)
编辑#2:更新和澄清完全改变了这个问题。
听起来你正在重新发明轮子并试图完成LINQ to SQL和LINQ to Entities已经完成的任务。例如,提供程序检查表达式树并将某些函数映射到SQL Server。您将承担一项微软已经为我们提供并经过广泛测试的大型任务。
使用现有的ORM解决方案会更好,无论是微软还是NHibernate等。
编辑#1:找到它,我知道我之前看到了一些东西,但它没有找到我。
您可以使用DataContext.GetCommand method来获取生成的SQL:
var query = dc.Persons.Take(1);
string generatedSql = dc.GetCommand(query).CommandText;
此示例从AdventureWorks数据库返回以下SQL:
SELECT TOP(1) [T 0]。[BusinessEntityID] [t0]。[PersonType],[t0]。[NameStyle], [t0]。[标题],[t0]。[FirstName], [t0]。[MiddleName],[t0]。[LastName], [t0]。[后缀],[t0]。[EmailPromotion], [T 0]。[AdditionalContactInfo] [t0]。[人口统计],[t0]。[rowguid] AS [Rowguid],[t0]。[ModifiedDate] FROM [人]。[人] AS [t0]
确定生成的语句的另一个选项将在VS2010中通过IntelliTrace(以前称为历史调试器)提供。有关详细信息和屏幕截图,请参阅此博文:Debugging LINQ to SQL queries using the Historical Debugger。
这在调试过程中唯一有用,并且没有提供以编程方式访问它的方法。
答案 2 :(得分:1)
您可以在DataBase上启动SQL Server Profiler来跟踪您的linq查询。
答案 3 :(得分:0)
为了将来参考,我认为这位绅士的方法是最好的http://damieng.com/blog/2008/07/30/linq-to-sql-log-to-debug-window-file-memory-or-multiple-writers
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; }
}
}
myDataContext.Log = new DebugTextWriter();
答案 4 :(得分:0)
我发现一个更简单的方法是使用“命令窗口”,而您无需输入任何其他代码。在这里,您可以在查询窗口中打印一个名为query的linq语句:
? (((System.Data.Objects.ObjectQuery)查询).ToTraceString()