我用
`.....
.....
query = query.Where(criterion, fiedNames);
string sql2 = ((ObjectQuery)query).ToTraceString();'
获取并调整将由LINQ执行的SQL代码。
当我快速观察时,我得到以下我不理解的SQL语句。
SELECT [UnionAll2].[C3] AS [C1], [UnionAll2].[C4] AS [C2],
[UnionAll2].[C5] AS [C3], [UnionAll2].[C6] AS [C4],
[UnionAll2].[C7] AS [C5],
[UnionAll2].[C8] AS [C6],
[UnionAll2].[C9] AS [C7],
..... few hundereds line more.....
@p__linq__4 AS [C2],
.....
CASE
WHEN ( [Join5].[id] IS NULL ) THEN
Cast(NULL AS INT)
WHEN ( @p__linq__0 = 1 )
.......
显然,如果我粘贴在SQL管理工作室并执行它,如果我没有传递@p__linq__0
的值,则会给我带来错误....
我的问题:如何获得可以在SQL管理上执行的跟踪SQL?
答案 0 :(得分:1)
你可以断言这个扩展方法:
/// <summary>
/// Traces IQueryable's DB query />
/// </summary>
/// <typeparam name="TEntity">IQueryable type</typeparam>
/// <param name="query">The IQueryable query</param>
/// <returns>Query</returns>
public static string ToTraceString<TEntity>(this IQueryable<TEntity> query)
{
StringBuilder sb = new StringBuilder();
var objQuery = query as ObjectQuery<TEntity>;
if (objQuery != null)
{
sb.AppendLine();
if(objQuery.Parameters.Count > 0)
{
sb.AppendLine("Query parameters:");
sb.AppendLine("--------------------------------------------------------------");
sb.AppendLine(" Name | Type | Value ");
sb.AppendLine("--------------------------------------------------------------");
foreach (var param in objQuery.Parameters)
{
sb.AppendFormat("{0, -20}|{1, -20}|{2, -20}{3}", param.Name, param.ParameterType.ToString(), param.Value, Environment.NewLine);
}
sb.AppendLine();
}
string partialQuery = objQuery.ToTraceString();
objQuery.Parameters.ToList().ForEach(p => partialQuery = partialQuery.Replace(":" + p.Name, p.Value.ToString()));
sb.AppendLine(partialQuery);
}
// replace
return sb.ToString();
}
答案 1 :(得分:1)
public class LinqProvider<T>
{
static readonly FieldInfo INTERNAL_QUERY_FIELD;
static readonly FieldInfo QUERYSTATE_FIELD;
static LinqProvider()
{
INTERNAL_QUERY_FIELD = typeof(DbQuery<T>).GetFields(BindingFlags.NonPublic | BindingFlags.Instance).FirstOrDefault(f => f.Name.Equals("_internalQuery"));
QUERYSTATE_FIELD = typeof(System.Data.Entity.Core.Objects.ObjectQuery<>).BaseType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance).FirstOrDefault(x => x.Name == "_state");
}
public IQueryable<T> QueryContext { get; set; }
InternalQuery _InternalQueryContext;
public InternalQuery InternalQueryContext
{
get
{
if (_InternalQueryContext == null)
{
_InternalQueryContext = new InternalQuery();
if (QueryContext is DbQuery<T>)
{
var internalQuery = INTERNAL_QUERY_FIELD.GetValue(QueryContext);
var objectQueryField = internalQuery.GetType().GetProperties().FirstOrDefault(f => f.Name.Equals("ObjectQuery"));
_InternalQueryContext.ObjectQueryContext = objectQueryField.GetValue(internalQuery) as System.Data.Entity.Core.Objects.ObjectQuery<T>;
}
else if (QueryContext is System.Data.Entity.Core.Objects.ObjectQuery<T>)
{
_InternalQueryContext.ObjectQueryContext = (QueryContext as System.Data.Entity.Core.Objects.ObjectQuery<T>);
}
}
return _InternalQueryContext;
}
}
public LinqProvider(IQueryable<T> queryContext)
{
QueryContext = queryContext;
}
public class InternalQuery
{
public System.Data.Entity.Core.Objects.ObjectQuery<T> ObjectQueryContext { get; set; }
public string ToTraceString(IDictionary<string, object> Parameters = null)
{
var state = QUERYSTATE_FIELD.GetValue(ObjectQueryContext);
var mi = state.GetType().GetMethods(BindingFlags.NonPublic | BindingFlags.Instance).FirstOrDefault(x => x.Name == "GetExecutionPlan");
mi.Invoke(state, new object[] { null });
var paramState = state.GetType().BaseType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance).FirstOrDefault(x => x.Name == "_parameters");
if (paramState != null)
{
System.Data.Entity.Core.Objects.ObjectParameterCollection col = paramState.GetValue(state) as System.Data.Entity.Core.Objects.ObjectParameterCollection;
if (col != null && Parameters != null)
{
foreach (var item in col)
{
Parameters.Add(item.Name, item.Value);
}
}
}
return ObjectQueryContext.ToTraceString();
}
}
}
答案 2 :(得分:0)
例如,将扩展方法名称更改为TraceString2,因为TraceString是相同的ObjectQuery方法名称。
此扩展,显示查询参数的所有数据(@p_ linq _0 ...):
using (var context = new MyEntities(true))
{
string cpty = "MiCpty";
DateTime date = DateTime.Today;
var query = context.CECA_SPECIAL_CAS.Where(a => a.IDACUERDO == cpty
&& a.FECHAENTRADA == date);
query.ToList();
System.Diagnostics.Debug.Print(query.ToTraceString2());
}
结果:
p_ linq _0 | System.String | MiCpty
p_ linq _1 | System.DateTime | 31/10/2013 00:00:00
选择 “Extent1”。“IDACUERDO”AS“IDACUERDO”, “Extent1”。“NOMBREPRINCIPAL”为“NOMBREPRINCIPAL”, “Extent1”。“NOMBRELEGAL”为“NOMBRELEGAL”, “Extent1”。“NOMBRELARGO”作为“NOMBRELARGO”, “Extent1”。“FECHAENTRADA”作为“FECHAENTRADA”, “Extent1”。“DIASEMANAOPERAR”作为“DIASEMANAOPERAR”, “Extent1”。“TIPOCONTRATO”AS“TIPOCONTRATO”, “Extent1”。“PERIODICIDAD”为“PERIODICIDAD”, “Extent1”。“DESC_PERIODICIDAD”AS“DESC_PERIODICIDAD”, “Extent1”。“ACTIVO”作为“ACTIVO”, “Extent1”。“MA_TYPE”AS“MA_TYPE”, “Extent1”。“MA_VERSION”为“MA_VERSION”, “Extent1”。“COLLATERALPORTFOLIOCODE”作为“COLLATERALPORTFOLIOCODE” 来自“CKCOL_ADM”。“CECA_SPECIAL_CA”“Extent1” WHERE((“Extent1”。“IDACUERDO”= MiCpty)AND(“Extent1”。“FECHAENTRADA”= 31/10/2013 00:00:00))
答案 3 :(得分:0)
您可以使用sql server 2008工具“Sql Server Profiler”查看执行的查询。