2015年09月14日

EntityFramework(3):Logプロパティ

   このエントリーをはてなブックマークに追加 Clip to Evernote
今回は、Logプロパティについて。次のコードで、どういったSQL文が発行されているか確認したいとします。

 using (var db = new NorthwindContext()) {
     var maxprice = db.Products.Select(p => p.UnitPrice).Max();
     Console.WriteLine("{0}", maxprice);
 }
それは、以下のような行を、NorthwindContext()を生成した直後に書いておくだけです。これで発行されたSQL文がコンソールに出力されます。

  db.Database.Log = sql => { Console.Write(sql); };


ただ、このシリーズでは、クエリの結果をコンソールに出力しているので、 SQL文もコンソールに出力されると結果の確認が面倒なので、SQL文はファイルに出力するようにしましょう。 とりあえず、以下のような 簡易Log クラスを定義します。

    static public class Log {
        public static void Write(string text) {
            File.AppendAllText("log.txt",text + Environment.NewLine);

        }
    }

実際は、NLog とか Log4Net とか使ってください。

で、最初に示したコードを以下のように書き換えます。

    using (var db = new NorthwindContext()) {
        db.Database.Log = sql => { Log.Write(sql); };
        var maxprice = db.Products.Select(p => p.ListPrice).Max();
        Console.WriteLine("{0}", maxprice);
    }

実際に実行してみてください。 
log.txt を見てみると、以下のSQL文が発行されているのを確認できます。

SELECT 
    [GroupBy1].[A1] AS [C1]
    FROM ( SELECT 
        MAX([Extent1].[UnitPrice]) AS [A1]
        FROM [dbo].[Products] AS [Extent1]
    )  AS [GroupBy1]

なんか想像してたものと違ってましたが、 まあ、ここは EntityFramework の内部の仕様の話なので深くは考えないことにします。

でも、いちいち

 db.Database.Log = sql => { Log.Write(sql); };

と書くのも面倒です。NorthwindContext クラスは、partial クラスとして定義されているので、
以下のようなクラスを別途定義しておきましょう。

    public partial class NorthwindContext : DbContext {
        public void SetLogging() {
            this.Database.Log = sql => { Log.Write(sql); };
        }
    }
そうすれば、NorthwindContext のインスタンスを生成した後に、
 db.SetLogging();
と書けばログ出力が可能になります。
なお、プロジェクトの作成時は、DatabaseFirstだけど、それ以降は、CodeFirstで 開発するというのであれば、自動生成された NorthwindContext.cs のコンストラクタ なりに、ログ出力の設定をしてしまっても良いかもしれませんね。
 

最後に、もうひとつ、どんなSQLが発行されるのか確認してみましょう。

   var query = db.Products
                 .OrderByDescending(x => x.UnitsInStock)
                 .Take(10);

このクエリの場合は、以下のSQLが発行されるのが確認できました。

SELECT TOP (10) 
    [Extent1].[ProductID] AS [ProductID], 
    [Extent1].[ProductName] AS [ProductName], 
    [Extent1].[SupplierID] AS [SupplierID], 
    [Extent1].[CategoryID] AS [CategoryID], 
    [Extent1].[QuantityPerUnit] AS [QuantityPerUnit], 
    [Extent1].[UnitPrice] AS [UnitPrice], 
    [Extent1].[UnitsInStock] AS [UnitsInStock], 
    [Extent1].[UnitsOnOrder] AS [UnitsOnOrder], 
    [Extent1].[ReorderLevel] AS [ReorderLevel], 
    [Extent1].[Discontinued] AS [Discontinued]
    FROM [dbo].[Products] AS [Extent1]
    ORDER BY [Extent1].[UnitsInStock] DESC


 

この記事へのトラックバックURL

http://trackback.blogsys.jp/livedoor/gushwell/52435101