代码之家  ›  专栏  ›  技术社区  ›  this. __curious_geek

从Linq表达式提取SQL查询

  •  14
  • this. __curious_geek  · 技术社区  · 15 年前

    是否可以从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;
    

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

    在此语句之后,“results”只保留Linq表达式,而不是由于延迟执行Linq查询而保留的结果。

    我可以从“results”中提取或生成Linq查询吗? 从中准备有效的SQL语句 查询存储在“linq”中?

    编辑

    我的目标是:

    我们已经写了自己的ORM。每次需要进行数据库操作时,我们都必须编写查询。现在我们需要在达尔把它处理掉。我们希望用代码编写LINQ表达式,该代码将根据我的ORM生成SQL语句,并在数据库中执行该SQL。

    我是否需要编写自定义的LINQ提供者来完成我需要的工作?

    5 回复  |  直到 6 年前
        1
  •  22
  •   jason    15 年前

    编辑:等等,你说的是Linq to对象?不,那是不可能的 . 无法将LINQ到对象查询的表达式树转换为表示查询某些数据库的表达式树。

    编辑:不要写你自己的ORM。对于这个问题,已经有了行之有效的解决方案。你再解决这个问题就是在浪费价值。如果要使用自己的ORM,将表达式转换为SQL语句,则必须编写自己的提供程序。这里有一个 walkthrough 在msdn上这样做。

    但说真的,不要写自己的ORM。五年前,NHibernate和Linq-to-SQL出现并成熟了,很好。但现在不行。没办法。

    此答案的其余部分假定您询问的是有关Linq to SQL的问题。

    我知道有两种方法。

    第一:

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

    var db = new MyDataContext();
    db.Log = Console.Out;
    

    这将在执行SQL语句时将其打印到控制台。有关此功能的更多信息,请参阅 MSDN . 其他地方有 examples 属于 TextWriter 允许将输出发送到调试器输出窗口的。

    第二:

    使用 LINQ to SQL Debug Visualizer 来自斯科特·古思里。这允许您通过Visual Studio中的调试器查看SQL语句。此选项的优点是,您可以在不执行查询的情况下查看SQL语句。甚至可以执行查询并在可视化工具中查看结果。

    可能不可能,但肯定很难。

        2
  •  15
  •   Ahmad Mageed    15 年前

    编辑第2页: 更新和澄清完全改变了问题。

    听起来你在重新设计方向盘,尝试完成linq-to-sql和linq-to-entities已经完成的工作。例如,提供程序检查表达式树并将某些函数映射到SQL Server。您将承担一项微软已经提供给我们并经过广泛测试的大任务。

    您最好使用现有的ORM解决方案,无论是微软的还是NHibernate等。


    编辑第1页: 找到了它,我知道我以前看到过一些东西,但我没想到。

    你可以使用 DataContext.GetCommand method 要获取生成的SQL,请执行以下操作:

    var query = dc.Persons.Take(1);
    string generatedSql = dc.GetCommand(query).CommandText;
    

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

    选择顶部(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]作为 [rowguid],[t0]。[modifieddate]来自 [人]。[人]为[t0]


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

    不过,这只在调试过程中很好,并不能提供一种以编程方式访问它的方法。

        3
  •  1
  •   user1089766    10 年前

    可以在数据库上启动SQL Server事件探查器来跟踪LINQ查询。

        4
  •  0
  •   user1477388    11 年前

    我想这位先生的方法是最好的 http://damieng.com/blog/2008/07/30/linq-to-sql-log-to-debug-window-file-memory-or-multiple-writers

    class DebugTextWriter : System.IO.TextWriter {
       public override void Write(char[] buffer, int index, int count) {
           System.Diagnostics.Debug.Write(new String(buffer, index, count));
       }
    
       public override void Write(string value) {
           System.Diagnostics.Debug.Write(value);
       }
    
       public override Encoding Encoding {
           get { return System.Text.Encoding.Default; }
       }
    }
    
    myDataContext.Log = new DebugTextWriter();
    
        5
  •  0
  •   Keenan Stewart    6 年前

    我发现一个更简单的方法是使用命令窗口,而您不需要输入任何额外的代码。在这里,您可以将名为query的LINQ语句打印到查询窗口:

    是吗?((system.data.objects.objectquery)查询).totraceString()