我正在阅读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的扩展可以在调试时为你生成这些字符串,那会不会很好?”
任何人都听说过这样的事情,如果有的话,你能指出我正确的方向吗?
谢谢!
答案 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