EF6 - 没有达到我的预期.Any()

时间:2017-04-24 09:13:01

标签: c# sql-server entity-framework-6 asp.net-4.5

我被EF 6难倒......我有一个Web应用程序,在性能方面表现非常糟糕。在分析时,我发现其中一个罪魁祸首是我的一种方法,它检查一个集合在EF6实体上是否为空(<或p>)。

基本上,我有:

public partial class BaseEntity
{
    public int BaseEntityId { get; set; }
    public string Name { get; set; }

    // a few more properties, of no concern here....

    // a lazily loaded collection of subitems        
    public virtual ICollection<Subitem> Subitems { get; set; }
}

public partial class Subitem
{
    public int SubitemId { get; set; }
    public int BaseEntityId { get; set; }
    public string Name { get; set; }

    // a few more properties, of no concern here....
}

在我的应用中,我需要检查BaseEntity的给定实例是否为&#34;空&#34; - 被定义为没有子项目。所以我将这个方法CheckIfEmpty添加到第二个部分类文件中:

public partial class BaseEntity
{
    public bool IsEmpty 
    {
        return !Subitems.Any();
    }
}        

现在单个BaseEntity可以有数百或数千个子项 - 所以我想用最有效的方法来检查是否有任何子项。我的假设是,对于尚未从数据库加载的集合调用.Any()基本上会转换为

IF EXISTS(SELECT * FROM dbo.Subitems) ......

SQL调用 - 或者其他类似的东西 - 只是检查是否存在任何项目。我特意选择.Any()而不是.Count > 0,因为我知道检查计数需要枚举整个集合,因此当我只想知道是否存在任何项目时,效率非常低。< / p>

不需要知道有多少存在,我也不感兴趣他们的细节 - 只需一个简单的 NO is empty?问题就足够了。

令我惊讶的是(以及bed bed),事实证明,EF6将这个简单的.Any()调用转换为SELECT语句,加载整个集合! - 那个&#39 ; s肯定我讨价还价......

有没有简单方法可以简单地检查如果尚未加载的集合有任何值 - 或者不是 - 没有从数据库加载完整的集合? ?

1 个答案:

答案 0 :(得分:5)

通过使用Eager加载方法并查询DbSet,您可以获得所需内容:

context.Set<TEntity>().Any();

被翻译成:

SELECT CASE WHEN EXISTS ( SELECT 1 FROM [TEntity] AS [m]) THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END