我正在进行一些EF查询优化。为了更好地理解查询性能,我正在研究生成的SQL,有些条件让我发疯:
WHERE (cast(1 as bit) <> cast(0 as bit))...
我无法想象一个案例,当这个条件评估为假时。也:
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
是实体的基类,其中Id
和ObjectVersion
(Entity
和VersionedEntity
都未映射到任何表格) :
public abstract class Entity
{
public virtual int Id { get; set; }
}
public abstract class VersionedEntity : Entity
{
public virtual byte[] ObjectVersion { get; set; }
}
答案 0 :(得分:1)
我不确定为什么 cast(1 as bit) <> cast(0 as bit)
,但有a work item in the EF backlog to remove this。我建议投票。我想这意味着它完全没用,因为该项目由RoMiller发布。它在查询中非常常见,我以前见过它。