簡體   English   中英

將Entity Framework 6模型生成的IQueryable轉換為SQL

[英]Converting IQueryable generated by Entity Framework 6 model into SQL

我的應用程序最初是使用Entity Framework 4和SQL Server以外的數據庫構建的。 我編寫了一個函數,該函數將IQueryable轉換為原始SQL,該SQL在執行時將發送到數據庫。 我之所以需要它,是因為我所使用的數據庫無法捕捉捕獲發送到服務器以執行的SQL的方法-沒有像SQL Server中的SQL Profiler工具那樣的工具。 我需要SQL,因此我可以測試所生成的查詢,並根據需要進行更改以優化性能。

我最近將應用程序升級到了Entity Framework 6,並且將IQueryable轉換為SQL的功能不再起作用。 功能如下:

public static string GetSql<T>( this IQueryable<T> query ) {
    string sql = ( (ObjectQuery<T>) query ).ToTraceString();

    ObjectQuery<T> q = query as ObjectQuery<T>;

    // Loop over the parameters in REVERSE ORDER!
    foreach ( ObjectParameter p in q.Parameters.OrderByDescending( p => p.Name ) ) {
        string pName = ":" + p.Name;

        if ( p.Value == null )
            sql = sql.Replace( pName, "NULL" );
        else {
            switch ( p.Value.GetType().Name ) {
                case "Boolean":            sql = sql.Replace( pName, (bool) p.Value ? "1" : "0" ); break;
                case "Byte":            sql = sql.Replace( pName, "0x" + ( (byte) p.Value ).ToString( "X2" ) ); break;
                case "DateTime":        sql = sql.Replace( pName, "'" + ( (DateTime) p.Value ).ToString() + "'" ); break;
                case "DateTimeOffset":    sql = sql.Replace( pName, "'" + ( (DateTimeOffset) p.Value ).ToString() + "'" ); break;
                case "Decimal":            sql = sql.Replace( pName, ( (Decimal) p.Value ).ToString() ); break;
                case "Double":            sql = sql.Replace( pName, ( (Double) p.Value ).ToString() ); break;
                case "Guid":            sql = sql.Replace( pName, "'" + ( (Guid) p.Value ).ToString( "D" ) + "'" ); break;
                case "Int16":            sql = sql.Replace( pName, ( (Int16) p.Value ).ToString() ); break;
                case "Int32":            sql = sql.Replace( pName, ( (Int32) p.Value ).ToString() ); break;
                case "Int64":            sql = sql.Replace( pName, ( (Int64) p.Value ).ToString() ); break;
                case "Single":            sql = sql.Replace( pName, ( (Single) p.Value ).ToString() ); break;
                case "String":            sql = sql.Replace( pName, "'" + (String) p.Value + "'" ); break;
                case "UInt16":            sql = sql.Replace( pName, ( (UInt16) p.Value ).ToString() ); break;
                case "UInt32":            sql = sql.Replace( pName, ( (UInt32) p.Value ).ToString() ); break;
                case "UInt64":            sql = sql.Replace( pName, ( (UInt64) p.Value ).ToString() ); break;
            }
        }
    }
        return sql;
}

這不起作用,因為IQueryable返回的IQueryable並非來自ObjectQuery 這是一個DbQuery 調用ToString方法將返回帶有參數的SQL。 我想用實際傳遞的值替換查詢中的參數,就像上面的代碼一樣,因此我可以將查詢粘貼到查詢工具中,而無需編輯它。

DbQuery類中似乎沒有Parameters集合,至少沒有該名稱的屬性。 如何在EF6中使用它?

實體框架6提供了一種靈活的方式來跟蹤發送給數據庫服務器執行的查詢。

Logging and Intercepting Database Operations

http://msdn.microsoft.com/en-us/data/dn469464.aspx

using (var context = new BlogContext()) 
{ 
    context.Database.Log = Console.Write; 

    var blog = context.Blogs.First(b => b.Title == "One Unicorn"); 

    blog.Posts.First().Title = "Green Eggs and Ham"; 

    blog.Posts.Add(new Post { Title = "I do not like them!" }); 

    context.SaveChangesAsync().Wait(); 
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM