我想知道如何在LinqToSql中跟蹤生成的SQL,如DataContext。在EF 4.1 DbContext中如何跟蹤生成的SQL
我還在Jaroslaw Kowalski的博客上閱讀了有關EFProviderWrapper解決方案的文章,但它基於ObjectContext,不適用於DbContext。
任何人都知道如何在DbContext中做到這一點?
謝謝。
我想知道如何在LinqToSql中跟蹤生成的SQL,如DataContext。在EF 4.1 DbContext中如何跟蹤生成的SQL
我還在Jaroslaw Kowalski的博客上閱讀了有關EFProviderWrapper解決方案的文章,但它基於ObjectContext,不適用於DbContext。
任何人都知道如何在DbContext中做到這一點?
謝謝。
MVC-Mini-Profiler是一個pwerful工具,不是ony trace生成的sql,而且是剖析工具。
Using mvc-mini-profiler database profiling with Entity Framework Code First
我使用SQL Server分析器工具來確切地查看已創建的SQL。也有http://efprof.com/但它有相當高的價格。
謝謝,我知道那個工具。我正在尋找一種DIY解決方案。 – Chance 2011-04-09 06:16:55
可以使用ObjectQuery.ToTraceString方法,以查看存儲命令(例如SQL語句)。 MSDN上的How To將向您展示如何使用它。
注意,在很多情況下,你就可以讓你有機會獲得ToTraceString方法施放一個IQueryable(從LINQ的擴展方法如IQueryable.Where返回類型)到的ObjectQuery。
這不太方便。我推薦這個:http://stackoverflow.com/questions/6550046/using-mvc-mini-profiler-database-profiling-with-entity-framework-code-first/6743941#6743941 – Chance 2011-07-20 04:43:13
最簡單的方法與DbContext
和DbSet<T>
只是使用ToString()
對IQueryable
你已經建成。例如:
var query = context.Blogs.Include(b => b.Posts)
.Where(b => b.Title == "AnyTitle");
string sql = query.ToString();
sql
包含當查詢被執行將被髮布到DB SQL命令。
這隻有在你做了搜索(返回一個IQueryable)。如果您要添加,修改和刪除實體,您如何查看該SQL? – codemonkey 2011-08-12 19:08:30
@codemonkey:True,僅適用於查詢。我不認爲有任何內置的方式來跟蹤DbContext的所有SQL語句。 – Slauma 2011-08-12 21:02:29
我來這裏問@codemonkey的問題。我發現的一切都表明前者,後者還沒有運氣。 – Funka 2013-01-26 01:34:16
我發現這裏的ObjectContext此EFTracingProvider擴展:
http://efwrappers.codeplex.com/
但這個例子是ObjectContext中沒有的DbContext,讓它用的DbContext 工作做在構造函數如下:
3210哦,並記住設置配置:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.diagnostics>
<sources>
<source name="EntityFramework.MyDbConnection" switchValue="All" />
</sources>
</system.diagnostics>
然後將所有SQL追蹤到即時窗口。
對於任何不想拉入第三方庫的人來說,只需查找包含參數的SQL(並且不會被所有反射所困擾),該擴展方法將從內部查詢對象和ObjectQuery對象DbQuery並在將參數實現回字符串後返回ToTraceString。如果它失敗,從IQueryable的返回參數少的ToString:
public static string ToSqlString<TEntity>(this IQueryable<TEntity> queryable) where TEntity : class
{
try
{
var dbQuery = queryable as DbQuery<TEntity>;
// get the IInternalQuery internal variable from the DbQuery object
var iqProp = dbQuery.GetType().GetProperty("InternalQuery", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
var iq = iqProp.GetValue(dbQuery);
// get the ObjectQuery internal variable from the IInternalQuery object
var oqProp = iq.GetType().GetProperty("ObjectQuery", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
var oq = oqProp.GetValue(iq);
var objectQuery = oq as ObjectQuery<TEntity>;
var sqlString = objectQuery.ToTraceString();
foreach (var objectParam in objectQuery.Parameters)
{
if (objectParam.ParameterType == typeof(string) || objectParam.ParameterType == typeof(DateTime) || objectParam.ParameterType == typeof(DateTime?))
{
sqlString = sqlString.Replace(string.Format("@{0}", objectParam.Name), string.Format("'{0}'", objectParam.Value.ToString()));
}
else if (objectParam.ParameterType == typeof(bool) || objectParam.ParameterType == typeof(bool?))
{
bool val;
if (Boolean.TryParse(objectParam.Value.ToString(), out val))
{
sqlString = sqlString.Replace(string.Format("@{0}", objectParam.Name), string.Format("{0}", val ? 1 : 0));
}
}
else
{
sqlString = sqlString.Replace(string.Format("@{0}", objectParam.Name), string.Format("{0}", objectParam.Value.ToString()));
}
}
return sqlString;
}
catch (Exception)
{
//squash it and just return ToString
return queryable.ToString();
}
}
當有超過10個參數時,此解決方案存在問題。假設一個參數被稱爲p10。當您用它的值替換p1時,最終會導致無效的SQL。 – 2014-06-16 21:46:03
執行你的代碼,然後運行該查詢,看看最後執行的SQL。
SELECT deqs.last_execution_time AS [Time], dest.TEXT AS [Query]
FROM sys.dm_exec_query_stats AS deqs
CROSS APPLY sys.dm_exec_sql_text(deqs.sql_handle) AS dest
ORDER BY deqs.last_execution_time DESC
這是相對於溶液(@kmk)略有改善,與值替換參數。此解決方案聲明並分配參數:
public static string ToSqlString<TEntity>(this IQueryable<TEntity> queryable) where TEntity : class
{
StringBuilder parametersBuilder = new StringBuilder();
try
{
var dbQuery = queryable as DbQuery<TEntity>;
// get the IInternalQuery internal variable from the DbQuery object
var iqProp = dbQuery.GetType().GetProperty("InternalQuery", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
var iq = iqProp.GetValue(dbQuery, null);
// get the ObjectQuery internal variable from the IInternalQuery object
var oqProp = iq.GetType().GetProperty("ObjectQuery", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
var oq = oqProp.GetValue(iq, null);
var objectQuery = oq as ObjectQuery<TEntity>;
var sqlString = objectQuery.ToTraceString();
foreach (var objectParam in objectQuery.Parameters)
{
SqlMetaData metadata = SqlMetaData.InferFromValue(objectParam.Value, objectParam.Name);
string sqlType = metadata.TypeName + (metadata.SqlDbType == SqlDbType.NVarChar ? "(" + metadata.MaxLength + ")" : String.Empty);
parametersBuilder.AppendFormat("declare @{0} {1} = '{2}'", objectParam.Name, sqlType, objectParam.Value);
parametersBuilder.AppendLine();
}
parametersBuilder.AppendLine();
return parametersBuilder.ToString() + sqlString;
}
catch (Exception)
{
//squash it and just return ToString
return queryable.ToString();
}
}
這實際上是非常好的問題。 – 2011-04-09 17:39:26
這是微軟希望你花費更多錢(Visual Studio Ultimate)的那些[功能](http://msdn.microsoft.com/en-us/magazine/ee336126.aspx)之一。有一些第三方庫可以讓它更容易。 – 2013-12-09 21:16:59