如何得到EF查询生成的SQL

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何得到EF查询生成的SQL相关的知识,希望对你有一定的参考价值。

在EF 4.1中,我们可以直接调用DbQuery<>的ToString()方法得到所生成的SQL。

using (var context = new MyDbContext())

    var people = from p in context.People
                 where p.PersonID > 100
                 select p;

    string sql = people.ToString();


所生成的SQL是:
SELECT 
[Extent1].[PersonID] AS [PersonID], 
[Extent1].[Name] AS [Name]
FROM [dbo].[People] AS [Extent1]
WHERE [Extent1].[PersonID] > 100
大 家应该已经猜到,这里的ToString()方法其实也就是调用了ObjectQuery<>的ToTraceString()方法。 DbQuery<>.ToString() ==> System.Data.Entity.Internal.Linq.InternalQuery<>.ToString()方法,此方法 在.NET Reflector得到的实现是这样的:
public override string ToString()

    return this._objectQuery.ToTraceString();
参考技术A 采用 SQL Server Profiler跟踪就可以捕捉到sql脚本哦

EF Code First 比较空值会生成奇怪的查询

【中文标题】EF Code First 比较空值会生成奇怪的查询【英文标题】:EF Code First comparing null values generates strange query 【发布时间】:2013-03-28 21:50:22 【问题描述】:

我正在尝试列出一些类别(父子关系),并且我有以下命令仅列出父类别

context.Categories.Where(c => c.ParentId == null)

但是EF生成的sql查询没有返回任何东西

EF生成的sql查询

SELECT 
CAST(NULL AS int) AS [C1], 
CAST(NULL AS varchar(1)) AS [C2], 
CAST(NULL AS bit) AS [C3], 
CAST(NULL AS int) AS [C4]
FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]
WHERE 1 = 0

类别模型

public class Category

  public int Id  get; set; 
  public string Name  get; set; 
  public bool IsActive  get; set; 
  public virtual IList<Category> SubCategories  get; set; 
  internal int? ParentId  get; set; 
  public virtual Category Parent  get; set; 

  public override bool Equals(object obj)
  
    var categoryToCompare = obj as Category;
    if (categoryToCompare == null) return false;

    return categoryToCompare.Id == Id;
  

  public override int GetHashCode()
  
    return Id.GetHashCode();
  

映射

public class CategoryConfiguration : EntityTypeConfiguration<Category>

  public CategoryConfiguration()
  
    ToTable("tbl_category");
    HasKey(c => c.Id);
    Property(c => c.Id).HasColumnName("cd_category");
    Property(c => c.Name).HasColumnName("ds_category");
    Property(c => c.IsActive).HasColumnName("fl_active");
    Property(c => c.ParentId).HasColumnName("cd_base_category").IsOptional();
    HasMany(c => c.SubCategories).WithRequired(c => c.Parent).HasForeignKey(c => c.ParentId);
  

【问题讨论】:

@caerolus 是 EF 生成的 使用(c =&gt; !c.ParentId.HasValue) @Fendy 生成相同的查询 我强烈建议将其设为公开,无论天气如何都能解决您当前的问题 映射有点奇怪,因为它根据需要定义了Parent,而 FK 属性可以为空。 【参考方案1】:

我将其发布为答案,因为肯定其中一个会起作用:

您的 ParentId 属性必须是 public virtual - 请先尝试更改它。

那么,试试context.Categories.Where(c =&gt; !c.ParentId.HasValue)

那么,试试context.Categories.Where(c =&gt; c.Parent == null)

我的应用程序可以正常运行。

那么,试试context.Categories.Where(c =&gt; object.Equals(c.Parent, null))

最后一个是bit of a hack from someone at MS,但显然应该可以。

【讨论】:

以上是关于如何得到EF查询生成的SQL的主要内容,如果未能解决你的问题,请参考以下文章

如何捕获 EF 生成的 SQL 脚本?

c# ef框架怎么使用linq语句多表查询?

如何编写转换为 T-SQL 的 EF Core 查询包含

EF 运行多个查询 - 如何更改为使用一个查询?

如何配置 EF Core 5 以使 MS SQL Server 数据库生成 Guid 密钥

EF查询视图只得到一条记录