如何将这个Entity Framework查询转换为SQL Server查询

3

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

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 查询以查看其输出?

1
你想看到这个查询生成的SQL语句,还是想要与这个EF查询等效的SQL语句? - MindSwipe
它生成的SQL查询。 - Hattori
你是在使用EF还是EF Core? - trashr0x
@trashr0x EF core. 我对这些方法的编写方式了解甚少,如果有人能指点我去参考文档,那真是太棒了。 - Hattori
你是否尝试使用SQL Profiler来捕获执行后的SQL查询? - cuong nguyen manh
2个回答

8
在 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);

IQueryable 强制转换为 ObjectQuery 并获取其跟踪字符串:
// 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();

拦截日志并将其打印到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配置创建一个拦截器并将其记录到文本文件中,方法见这里
<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>

4. 最后,你可以使用LinqPad。有一个免费的版本可以连接到数据库,在其中直接输入C#表达式或语句,并在底部显示生成的SQL,类似于这个Screenshot of LinqPad 6

0

DbContext.Database.Log 属性可以设置为接受字符串参数的任何方法的委托。在这个例子中,SQL语句将被写入控制台,使用 Console.Write。

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();
}

来自: https://learn.microsoft.com/zh-cn/ef/ef6/fundamentals/logging-and-interception


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接