9

我正在阅读一篇关于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

4 回答 4

4

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

更新:(复杂部分)它是如何实现的?

实际的字符串生成是按System.Data.Linq.SqlClient.SqlProvider类完成的。它有 hidden 方法string IProvider.GetQueryText(Expression query),它基于传递的表达式构建 SQL 查询文本。这个方法被内部接口隐藏了IProvider,所以调用它并不是一件小事。

于 2012-10-25T15:24:43.420 回答
2

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

于 2012-10-25T15:10:40.223 回答
2

您可以将该DataContext.Log属性设置为TextWriter(例如Console.Out)以查看生成的 SQL ,但我认为这不会让您在不执行 SQL 的情况下输出它

于 2012-10-25T15:14:00.750 回答
1

一个可怕的hacky解决方案:

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

于 2012-10-25T15:56:32.993 回答