Для тех, кто не хочет загружать стороннюю библиотеку и просто ищет SQL, содержащий параметры (и не огорчает все отражение), этот метод расширения извлекает объект InternalQuery и объект ObjectQuery изDbQuery и возвращает ToTraceString после реализации параметров обратно в строку.В случае неудачи он возвращает ToString без параметров из IQueryable:
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();
}
}