是否存在将IQueryable <t> lambda表达式转换为SQL字符串的api或扩展名?</t>

时间:2012-10-25 15:08:22

标签: c# linq linq-to-sql iqueryable

我正在阅读Linq to Sql上的一篇文章并遇到了这个问题:

IQueryProvider provider = new QueryProvider(database.GetCommand, database.ExecuteQuery);
IQueryable<Product> source = new Queryable<Product>(provider, database.GetTable<Product>());
IQueryable<string> results = source.Where(product => product.CategoryID == 2)
                                   .OrderBy(product => product.ProductName)
                                   .Select(product => product.ProductName)
                                   .Skip(5)
                                   .Take(10);

然后,作者将结果翻译成普通的sql:

exec sp_executesql N'SELECT [t1].[ProductName]
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY [t0].[ProductName]) AS [ROW_NUMBER], [t0].[ProductName]
FROM [dbo].[Products] AS [t0]
WHERE [t0].[CategoryID] > @p0
) AS [t1]
WHERE [t1].[ROW_NUMBER] BETWEEN @p1 + 1 AND @p1 + @p2
ORDER BY [t1].[ROW_NUMBER]',N'@p0 int,@p1 int,@p2 int',@p0=2,@p1=5,@p2=10

而且我心里想,“神圣的牛!如果有一个IQueryable的扩展可以在调试时为你生成这些字符串,那会不会很好?”

任何人都听说过这样的事情,如果有的话,你能指出我正确的方向吗?

谢谢!

4 个答案:

答案 0 :(得分:4)

使用Linq to Sql,您可以调用query.Provider.ToString(),这将返回查询文本(顺便说一句,您可以在调试时在Visual Studio中查看相同的属性)。

更新:(复杂部分)如何实施?

实际字符串生成由System.Data.Linq.SqlClient.SqlProvider类完成。它有隐藏方法string IProvider.GetQueryText(Expression query),它基于传递的表达式构建SQL查询文本。内部接口IProvider隐藏了此方法,因此调用它并非易事。

答案 1 :(得分:2)

我认为Linqpad可用于在SQL和Linq之间进行转换,希望有所帮助。

答案 2 :(得分:2)

您可以将DataContext.Log属性设置为TextWriter(例如Console.Out)以查看SQL 生成时的,但我不认为这使您可以输出SQL 而不执行它

答案 3 :(得分:1)

一个可怕的黑客解决方案:

如前所述使用DataContext.Log,但只需将所有内容包装在事务和回滚中。 ; P