首页 > 解决方案 > 如何将此实体框架查询转换为 SQL Server 查询

问题描述

我有一个查询,其格式如下:

bool filterQuotes = false;
bool filterInactive = false;
var res = await DbContext.CheckPlans
                .Where(plan => plan.PlanID == currentPlanId)
                .SelectMany(plan => plan.CheckActivityPlanDetail)
                .Include(planDetail => planDetail.CheckActivity)
                .ThenInclude(checkActivity => checkActivity.Setup)
                .Where(planDetail => (!filterQuotes || planDetail.CheckActivity.ActivityType==0)
                    && (!filterInactive || planDetail.IsActive))
                .OrderBy(planDetail => planDetail.CheckActivity.Setup.Value)
                .ToListAsync();

如何将此查询转换为普通 SQL Server 查询以查看其输出是什么?

标签: c#sqlsql-serverentity-framework

解决方案


在 Entity Framework 中,有几种方法可以查看查询生成的 SQL。

注意:所有这些方式都将使用此查询:

var query = DbContext.CheckPlans
                .Where(plan => plan.PlanID == currentPlanId)
                .SelectMany(plan => plan.CheckActivityPlanDetail)
                .Include(planDetail => planDetail.CheckActivity)
                .ThenInclude(checkActivity => checkActivity.Setup)
                .Where(planDetail => (!filterQuotes || planDetail.CheckActivity.ActivityType==0)
                    && (!filterInactive || planDetail.IsActive))
                .OrderBy(planDetail => planDetail.CheckActivity.Setup.Value);
  1. 转换IQueryable为 anObjectQuery并获取它的跟踪字符串:
// ObjectQuery is in the 'System.Data.Objects' namespace if EF version < 6
// starting with EF version 6 and upwards it's in the 'System.Data.Entity.Core.Objects' namespace
var sql = ((ObjectQuery) query).ToTraceString();
  1. 拦截日志并将其打印到Debug.WriteLine
// This code needs to be placed where you are creating your DbContext
context.Database.Log = s => Debug.WriteLine(s);

// ...
// Then when executing the query with
var results = query.ToListAsync();
// Your debug console in Visual Studio should contain all the information you need
  1. 实体框架配置。
    如果您使用的是 EF 6.1 及更高版本,则可以使用 EF 配置创建拦截器并将其记录到 txt 文件中,如下所述
<interceptors>
  <interceptor type="System.Data.Entity.Infrastructure.Interception.DatabaseLogger, EntityFramework">
    <parameters>
      <parameter value="C:\Temp\LogOutput.txt"/>
      <parameter value="true" type="System.Boolean"/>
    </parameters>
  </interceptor>
</interceptors>
  1. 最后,您可以使用LinqPad。有一个可以连接数据库的免费版本,可以直接输入C#表达式或语句,生成的SQL会显示在底部,类似这样LinqPad 6 截图

推荐阅读