从LINQ表达式中提取sql查询

thi*_*eek 14 c# linq linq-to-sql

是否可以从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;
Run Code Online (Sandbox Code Playgroud)

alt text http://ruchitsurati.net/files/linq-debugging.png

在此语句之后,'results'仅保留LINQ表达式而不是由于延迟执行LINQ查询而导致的结果.

我可以从'结果'中提取或生成LINQ查询,并从存储在'LINQ'中的查询中准备一个有效的SQL语句吗?

编辑

这是我的目标:

我们已经编写了自己的ORM.我们每次需要进行数据库操作时都必须编写查询.现在我们需要在DAL摆脱它.我们希望在代码中编写LINQ表达式,它将针对我的ORM生成SQL语句,我们将在数据库上执行此SQL.

我是否愿意编写我的定制Linq提供商来做我需要的事情?

jas*_*son 22

编辑:等等,你在谈论LINQ to Objects?不,那是不可能的1.无法将LINQ to Object查询的表达式树转换为表示查询某些数据库的表达式树.

编辑:不要写你自己的ORM.这个问题有成熟的解决方案.你试图再次解决这个问题就是在浪费价值.如果您要使用自己的ORM,将表达式转换为SQL语句,是的,您必须编写自己的提供程序.这是MSDN上的一个演练.

但严重的是,不要写自己的ORM.五年前,NHibernate和LINQ to SQL出现并成熟,很好.但是不是现在.没门.

这个答案的其余部分假设您在询问LINQ to SQL.

我知道有两种方法.

第一:

DataContext.Log属性设置为Console.Out(或System.IO.TextWriter您选择的其他):

var db = new MyDataContext();
db.Log = Console.Out;
Run Code Online (Sandbox Code Playgroud)

这将在执行时将SQL语句打印到控制台.有关此功能的更多信息,请参阅MSDN.在其他地方也有例子TextWriter,让你的输出发送到调试器输出窗口秒.

第二:

使用Scott Guthrie 的LINQ to SQL Debug Visualizer.这允许您通过Visual Studio中的调试器查看SQL语句.此选项的优点是您可以在不执行查询的情况下查看SQL语句.您甚至可以执行查询并在可视化工具中查看结果.

1:也许并非不可能,但肯定非常难.

  • +1"认真,不要写自己的ORM" (6认同)

Ahm*_*eed 16

编辑#2:更新和澄清完全改变了问题.

听起来你正在重新发明轮子并试图完成LINQ to SQL和LINQ to Entities已经完成的任务.例如,提供程序检查表达式树并将某些函数映射到SQL Server.您将承担Microsoft已经为我们提供并进行广泛测试的大型任务.

使用现有的ORM解决方案会更好,无论是Microsoft还是NHibernate等.


编辑#1:发现它,我知道我之前看到了一些东西,但它没有找到我.

您可以使用DataContext.GetCommand方法来获取生成的SQL:

var query = dc.Persons.Take(1);
string generatedSql = dc.GetCommand(query).CommandText;
Run Code Online (Sandbox Code Playgroud)

此示例从AdventureWorks数据库返回以下SQL:

SELECT TOP(1)[t0].[BusinessEntityID],[t0].[PersonType],[t0].[NameStyle],[t0].[Title],[t0].[FirstName],[t0].[ MiddleName],[t0].[LastName],[t0].[Suffix],[t0].[EmailPromotion],[t0].[AdditionalContactInfo],[t0].[Demographics],[t0].[rowguid] AS [Rowguid],[t0].[ModifiedDate] FROM [Person].[Person] AS [t0]


确定生成的语句的另一个选项将在VS2010中通过IntelliTrace(以前称为历史调试器)提供.有关更多信息和屏幕截图,请参阅此博客文章:使用Historical Debugger调试LINQ to SQL查询.

但这在调试期间才有用,并且没有提供以编程方式访问它的方法.