c# - 生成的 SQL 查询中的奇怪条件

标签 c# entity-framework entity-framework-5

我正在研究一些 EF 查询优化。为了更好地了解查询性能,我正在研究生成的 SQL,有些情况让我抓狂:

WHERE (cast(1 as bit) <> cast(0 as bit))...

我无法想象这种情况何时会评估为 false。还有:

CASE WHEN ([Extent9].[Id] IS NULL) THEN...

显然,[Extent9].[Id]表示对应表中的主键列,当然不能为NULL

为什么这些条件会出现在 SQL 中? 这是 LINQ 查询文本,如果它可以帮助回答问题的话:

var query = _context
    .Objects
    .Where(o => o.DatawareVersionId == _datawareId);
    .SelectMany(t => t.ComplexSubTasks)
    .Where(st => st.Variant.Order.CurrentAlgoVersion != null)
    .Select(st => st.Variant.Order.CurrentAlgoVersion)
    .OfType<MonitoringAlgoVersion>()
    .Where(version => version != null && version.Applicabilities.Any(applicability => applicability.SymbolicCircuitTypeId == _typeId))
    .Any());
    .Select(o => o.Group)
    .Distinct();

更新。 完整的 SQL 语句:

SELECT 
[Distinct1].[Id] AS [Id], 
[Distinct1].[GenericGroup] AS [GenericGroup], 
[Distinct1].[Number] AS [Number], 
[Distinct1].[Group] AS [Group]
FROM ( SELECT DISTINCT 
    [Extent2].[Id] AS [Id], 
    [Extent2].[GenericGroup] AS [GenericGroup], 
    [Extent2].[Number] AS [Number], 
    [Extent2].[Group] AS [Group]
    FROM  [dbo].[Objects] AS [Extent1]
    INNER JOIN [dbo].[ObjectGroups] AS [Extent2] ON [Extent1].[GroupId] = [Extent2].[Id]
    WHERE ([Extent1].[DatawareVersionId] = @p__linq__0) AND ( EXISTS (SELECT 
        1 AS [C1]
        FROM ( SELECT 
            [Extent9].[Id] AS [Id]
            FROM       [dbo].[Tasks] AS [Extent3]
            INNER JOIN [dbo].[SubTasks] AS [Extent4] ON [Extent3].[Id] = [Extent4].[TaskId]
            LEFT OUTER JOIN [dbo].[Variants] AS [Extent5] ON [Extent4].[VariantId] = [Extent5].[Id]
            LEFT OUTER JOIN [dbo].[Orders] AS [Extent6] ON [Extent5].[OrderId] = [Extent6].[Id]
            INNER JOIN [dbo].[AlgoVersions] AS [Extent7] ON [Extent6].[CurrentAlgoVersion] = [Extent7].[Id]
            LEFT OUTER JOIN [dbo].[Orders] AS [Extent8] ON [Extent5].[OrderId] = [Extent8].[Id]
            LEFT OUTER JOIN [dbo].[AlgoVersions] AS [Extent9] ON [Extent8].[CurrentAlgoVersion] = [Extent9].[Id]
            WHERE (cast(1 as bit) <> cast(0 as bit)) AND ([Extent1].[Id] = [Extent3].[ObjectId]) AND (CASE WHEN ([Extent9].[Id] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE '10X0X' END LIKE '10X0X%')
        )  AS [Project1]
        WHERE  EXISTS (SELECT 
            1 AS [C1]
            FROM [apot].[draw_algo_versions_applicability] AS [Extent10]
            WHERE ([Project1].[Id] = [Extent10].[algo_version_id]) AND ([Extent10].[schema_type_id] = @p__linq__1)
        )
    ))
)  AS [Distinct1]

更新 2。 这是映射到 AlgoVersions 表的实体类型:

public abstract class AlgoVersion : VersionedEntity
{           
    public virtual int OrderId { get; set; }
    public virtual Order Order { get; set; }
    public virtual bool IsErrorFixed { get; set; }
    public virtual bool IsFunctionalityExtended { get; set; }
    public virtual ObservableCollection<AlgoVersionStatus> Statuses { get; set; }
}

public class MonitoringAlgoVersion : AlgoVersion
{
    public virtual ObservableCollection<TemplateGroup> TemplateGroups { get; set; }
    public virtual ObservableCollection<MonitoringAlgoVersionApplicability> Applicabilities { get; set; }
}

其中 VersionedEntity 是实体的基类,它具有 IdObjectVersion(EntityVersionedEntity 未映射到任何表):

public abstract class Entity
{
    public virtual int Id { get; set; }
}

public abstract class VersionedEntity : Entity
{
    public virtual byte[] ObjectVersion { get; set; }
}

最佳答案

我不确定为什么 cast(1 as bit) <> cast(0 as bit)在那里但是有a work item in the EF backlog to remove this .我建议投票给它。我想这意味着它完全没用,因为该项目是由 RoMiller 发布的。它在查询中很常见,我以前经常看到它。

关于c# - 生成的 SQL 查询中的奇怪条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19095896/

相关文章:

c# - 以最低键值获取键值对的最便宜方法?

c# - 在 C# 中将巨型 bool 数组保存/加载到磁盘?

entity-framework - 找不到为 Entity Framework 创建的属性的 PropertyGrid Browsable,如何找到它?

c# - EF 中的事务性 SaveChangesAsync

entity-framework - EF Code First - 创建数据库 - 用户登录失败

c# - 具有流畅 api 的 Entity Framework 唯一键?

c# - 更改屏幕的滤色器以与多个显示器一起使用

c# - Entity Framework 。违反 UNIQUE KEY 约束

c# - 使用简单注入(inject)器的更新数据库,没有 services.AddDbContext<>()

c# - 如何使用 EF 5.0 Code First 启用并发检查?