web-dev-qa-db-ja.com

LINQ式からSQLクエリを抽出します

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;

代替テキストhttp://ruchitsurati.net/files/linq-debugging.png

このステートメントの後、「results」はLINQ式のみを保持し、LINQクエリの実行が延期されたために結果は保持されません。

「結果」からLINQクエリを抽出または生成し、「LINQ」に格納されているクエリから有効なSQLステートメントを準備できますか?

編集

これが私の目的です:

独自のORMを作成しました。データベース操作を行う必要があるたびに、クエリを作成する必要があります。今、私たちはDALでそれを取り除く必要があります。 ORMに対してSQLステートメントを生成するコードでLINQ式を記述し、このSQLをデータベースで実行します。

必要なことを実行するためにカスタムLinqプロバイダーを作成する必要がありますか?

14

編集:待ってください、あなたはLINQ to Objectsについて話しているのですか?いいえ、それは不可能です1。 LINQ toObjectクエリの式ツリーをデータベースのクエリを表す式ツリーに変換する方法はありません。

編集:あなた自身のORMを書かないでください。この問題には実証済みの解決策があります。この問題をもう一度解決しようとすると、価値が無駄になります。独自のORMを使用して、式をSQLステートメントに変換する場合は、はい、独自のプロバイダーを作成する必要があります。これが ウォークスルー MSDNでそれを行っています。

しかし、真剣に、あなた自身のORMを書かないでください。 NHibernateとLINQto SQLが登場して成熟する前の5年前、問題ありませんでした。しかし今ではない。ありえない。

この回答の残りの部分は、LINQ toSQLについて質問していることを前提としています。

私が知っている2つの方法があります。

最初:

をセットする - DataContext.Log プロパティからConsole.Out(または別のSystem.IO.TextWriter お好みの):

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

これにより、SQLステートメントが実行されるときにコンソールに出力されます。この機能の詳細については、 [〜#〜] msdn [〜#〜] を参照してください。他の場所には examples of TextWritersがあり、デバッガーの出力ウィンドウに出力を送信できます。

2番目:

Scott Guthrieの LINQ to SQL Debug Visualizer を使用します。これにより、VisualStudioのデバッガーを介してSQLステートメントを確認できます。このオプションには、クエリを実行せずにSQLステートメントを表示できるという利点があります。クエリを実行して、ビジュアライザーで結果を確認することもできます。

1:おそらく不可能ではありませんが、確かに非常に難しいです。

22
jason

編集#2:更新と説明により、質問が完全に変わりました。

車輪の再発明を行い、LINQ toSQLとLINQtoEntitiesがすでに達成していることを達成しようとしているようです。たとえば、プロバイダーは式ツリーを調べて、特定の関数をSQLServerにマップします。あなたは、マイクロソフトがすでに提供し、広範囲にわたってテストした大きなタスクを引き受けることになります。

MicrosoftやNHibernateなど、既存のORMソリューションを使用する方がはるかに良いでしょう。


編集#1:それを見つけました、私は以前にこれのために何かを見たことを知っていましたが、それは私を逃しました。

DataContext.GetCommandメソッド を使用して、生成されたSQLを取得できます。

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

この例では、AdventureWorksデータベースから次のSQLが返されます。

SELECT TOP(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] AS [Rowguid]、[t0]。[ModifiedDate] FROM [Person]。[Person] AS [t0]


生成されたステートメントを決定する別のオプションは、IntelliTrace(以前はHistorical Debuggerと呼ばれていました)を介してVS2010で使用できるようになります。詳細とスクリーンショットについては、次のブログ投稿を参照してください。 Historical Debuggerを使用したLINQ to SQLクエリのデバッグ

ただし、これはデバッグ中にのみ有効であり、プログラムでアクセスする方法を提供しません。

16
Ahmad Mageed

データベースでSQLServer Profilerを起動して、linqクエリをトレースできます。

1
user1089766

私が見つけたより簡単な方法は、コマンドウィンドウを使用することであり、追加のコードを入力する必要はありませんでした。ここで、queryというlinqステートメントをクエリウィンドウに出力できます。

? ((System.Data.Objects.ObjectQuery)query).ToTraceString()

0
Keenan Stewart

今後の参考のために、この紳士の方法が最善だと思います http://damieng.com/blog/2008/07/30/linq-to-sql-log-to-debug-window-file-memory-または-複数のライター

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();
0
user1477388