【发布时间】:2015-12-26 14:31:34
【问题描述】:
在我的数据库中有Document 和DocumentFile 表。主键 - 列 Uid(在两个表中)。 DocumentFile 通过列 DocumentUid 引用 Document。
我知道文档文件的 uid,我想选择带有文件的文档(左连接),EF 生成这个查询:
DECLARE @p__linq__0 uniqueidentifier,@p__linq__1 uniqueidentifier,@p__linq__2 varchar(max) ,@p__linq__3 nvarchar(max) ,@p__linq__4 uniqueidentifier
SELECT @p__linq__0=NULL,@p__linq__1=NULL,@p__linq__2=NULL,@p__linq__3=NULL,@p__linq__4='8670AD28-9FA6-41F3-94B9-6B91FD2AE110'
SELECT
*
FROM [dbo].[Document] AS [Extent1]
LEFT OUTER JOIN [dbo].[DocumentFile] AS [Extent2] ON [Extent1].[Uid] = [Extent2].[DocumentUid]
WHERE ((([Extent1].[EntityUid] = @p__linq__0) AND (@p__linq__0 IS NOT NULL)) OR (@p__linq__1 IS NULL))
AND ((([Extent1].[EntityTypeCode] = @p__linq__2) AND ( NOT ([Extent1].[EntityTypeCode] IS NULL OR @p__linq__2 IS NULL))) OR (([Extent1].[EntityTypeCode] IS NULL) AND (@p__linq__2 IS NULL)) OR (@p__linq__3 IS NULL) OR (( CAST(LEN(@p__linq__3) AS int)) = 0))
AND ((([Extent2].[Uid] = @p__linq__4) AND ( NOT ([Extent2].[Uid] IS NULL OR @p__linq__4 IS NULL))) OR (([Extent2].[Uid] IS NULL) AND (@p__linq__4 IS NULL)) )
(用星号替换的一长列列和顶部声明的参数,但没关系)
对于复杂的查询计划(约 20 秒),此查询的运行速度非常慢。如果我在查询结束时评论此条件:
/*OR (([Extent2].[Uid] IS NULL) AND (@p__linq__4 IS NULL))*/
它以闪电般的速度运行(几毫秒)。 Extent2 是 DocumentFile,列 Uid 是主键,它永远不会是 NULL。
在 C# 代码列 Uid 声明为 Guid:
public class DocumentFile
{
public const string EntityType = "DocumentFile";
[Key]
public Guid Uid { get; set; }
public Guid DocumentUid { get; set; }
...
}
如何修复查询或告诉 SQL Server 使用简单的查询计划,例如带有注释条件的查询?
【问题讨论】:
-
如果要选择带文件的文档,为什么要使用外连接而不是内连接?
-
在某些情况下文档可能是空的,文档中没有文件。但我想选择文档本身。
-
您的 LINQ 查询是什么?也许这可以解释为什么它会为键列生成空检查。如果该列在数据库中被定义为可为空(真的不知道键列如何/为什么为空),也许您可以将
RequiredAttribute添加到Uid以告诉 EF 该列不能null,也许这样它会从生成的 sql 语句中删除 null 检查。 -
RequiredAttribute 不会改变任何东西。 Linq 查询并不简单,它在某些地方进行了修改-添加了条件。如果找不到解决方案,我稍后会编辑我的帖子。
-
这个问题我没仔细看但是让我想起了stackoverflow.com/a/18952559/73226
标签: sql sql-server entity-framework tsql