我的应用程序最初是使用Entity Framework 4和SQL Server以外的数据库构建的。我编写了一个函数,它将IQueryable
转换为原始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;
}
这不起作用,因为EF6返回的IQueryable
不会从ObjectQuery
下降。这是一个DbQuery
。调用ToString
方法返回带有参数的SQL。我想用实际传递的值替换查询中的参数,如上面的代码那样,所以我可以将查询粘贴到查询工具中而不进行编辑。
Parameters
类似乎没有DbQuery
集合,至少没有具有该名称的属性。如何在EF6中使用它?
答案 0 :(得分:1)
实体框架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();
}