将IQueryable实例转换为字符串中的LINQ语法

时间:2010-06-10 13:56:59

标签: linq c#-3.0

我想知道是否有人将IQueryable实例格式化为字符串中的LINQ C#语法。对于我正在构建的内部LINQ-to-SQL审计框架来说,这是一个很好的功能。一旦我的框架从数据存储库方法获取IQueryable实例,我想输出如下内容:

此LINQ查询:

from ce in db.EiClassEnrollment
join c in db.EiCourse on ce.CourseID equals c.CourseID
join cl in db.EiClass on ce.ClassID equals cl.ClassID
join t in db.EiTerm on ce.TermID equals t.TermID
join st in db.EiStaff on cl.Instructor equals st.StaffID
where (ce.StudentID == studentID) && (ce.TermID == termID) && (cl.Campus == campusID)
select new { ce, cl, t, c, st };

生成以下LINQ-to-SQL查询:

DECLARE @p0 int;
DECLARE @p1 int;
DECLARE @p2 int;
SET @p0 = 777;
SET @p1 = 778;
SET @p2 = 779;
SELECT [t0].[ClassEnrollmentID], ..., [t4].[Name]
FROM [dbo].[ei_ClassEnrollment] AS [t0]
INNER JOIN [dbo].[ei_Course] AS [t1] ON [t0].[CourseID] = [t1].[CourseID]
INNER JOIN [dbo].[ei_Class] AS [t2] ON [t0].[ClassID] = [t2].[ClassID]
INNER JOIN [dbo].[ei_Term] AS [t3] ON [t0].[TermID] = [t3].[TermID]
INNER JOIN [dbo].[ei_Staff] AS [t4] ON [t2].[Instructor] = [t4].[StaffID]
WHERE ([t0].[StudentID] = @p0) AND ([t0].[TermID] = @p1) AND ([t2].[Campus] = @p2)

我已经有了SQL输出,你可以看到。我只需要找到一种方法来将IQueryable转换为表示其原始LINQ语法的字符串(具有可接受的转换丢失)。我不怕自己写这篇文章,但我想先看看是否还有其他人这样做过。

3 个答案:

答案 0 :(得分:1)

最好的解决方法是在C#中阅读表达式树。我认为您可以使用IQueryable<T>类型的访问者模式来恢复C#语法。我知道Expression<Func<T>>有一些实现可用,但我记不起在LINQ查询中看到过这种情况。

更新我对此感到好奇并开始做一些研究。您可以通过Expression的{​​{1}}属性访问基础表达式树。看起来您需要实现一个呈现C#而不是SQL的LINQ提供程序。这远非微不足道。事实上,我认为除非这是一个教育(非商业)项目,否则很难证明所需的工作量是合理的。但是,如果你无所畏惧,here看起来就像LINQ提供商的优秀教程。 Codeplex上也提供了所有源代码。

答案 1 :(得分:1)

可以将所有IQueryable编译到Expression对象中。表达式具有Body属性,表示lambda表达式的主体。您可以在解析源代码时编译每个表达式,然后输出正文化的正文。

答案 2 :(得分:0)

我已经为此完成了自己的实现,因为我找不到任何可以免费获得或源代码形式的现有工作。我发布了一篇关于我的工作的快速博客文章,并包含了整个C#源代码。你可以用它做一些漂亮的东西。请随意查看。

http://bittwiddlers.org/?p=120