C# SQL Server中的EF核心参数嗅探

C# SQL Server中的EF核心参数嗅探,c#,sql-server,entity-framework-core,parameter-sniffing,C#,Sql Server,Entity Framework Core,Parameter Sniffing,我一直在看Brent Ozar的培训视频(我的SQL专家),他谈到了参数嗅探,并说EF可以做到这一点,但就我而言,我无法让一个例子起作用。我本来希望看到参数,但它只是创建了这样的SQL,只有相等,而不是@p1,@p2 SELECT [p].[Id], [p].[Body], [p0].[Type] FROM [Posts] AS [p] INNER JOIN [PostTypes] AS [p0] ON [p].[PostTypeId] = [p0].[Id] WHERE ([p].[PostT

我一直在看Brent Ozar的培训视频(我的SQL专家),他谈到了参数嗅探,并说EF可以做到这一点,但就我而言,我无法让一个例子起作用。我本来希望看到参数,但它只是创建了这样的SQL,只有相等,而不是@p1,@p2

SELECT [p].[Id], [p].[Body], [p0].[Type]
FROM [Posts] AS [p]
INNER JOIN [PostTypes] AS [p0] ON [p].[PostTypeId] = [p0].[Id]
WHERE ([p].[PostTypeId] = 6) AND ([p].[CreationDate] >= '2011-01-01T00:00:00.000')
我从StackOverflow2013数据库中创建了DBContext,并在post类型上创建了一个外键以获得某种连接

有人知道我如何得到一个使用EF进行参数嗅探的示例,因为这每次只会创建一个新的查询计划

如果调用存储过程,则可以进行参数嗅探

我的C#代码如下

  var result = ctx.Posts
    .Include(x => x.PostType)
    .Where(x => x.PostTypeId == 6 && x.CreationDate >= new DateTime(2013, 01, 01))
        .Select(x => new {
           Id = x.Id,
           Body = x.Body, 
           Type = x.PostType.Type
         }).ToList();

在我找到答案后不久:)

正如Gert在评论中所说,我必须传递一个变量,因此EF在那里发挥了一些魔力。 因此,如果我将代码更改为此,则会发生:

var myId = 6;

var result = ctx.Posts
    .Include(x => x.PostType)
    .Where(x => x.PostTypeId == myId && x.CreationDate >= new DateTime(2013, 01, 01))
        .Select(x => new {
            Id = x.Id,
            Body = x.Body, 
            Type = x.PostType.Type
        }).ToList();
然后我得到这样的SQL

exec sp_executesql N'SELECT [p].[Id], [p].[Body], [p0].[Type]
FROM [Posts] AS [p]
INNER JOIN [PostTypes] AS [p0] ON [p].[PostTypeId] = [p0].[Id]
WHERE ([p].[PostTypeId] = @__myId_0) AND ([p].[CreationDate] >= ''2013-01-01T00:00:00.000'')',N'@__myId_0 int',@__myId_0=6
然后我可以用不同的值执行另一个

exec sp_executesql N'SELECT [p].[Id], [p].[Body], [p0].[Type]
FROM [Posts] AS [p]
INNER JOIN [PostTypes] AS [p0] ON [p].[PostTypeId] = [p0].[Id]
WHERE ([p].[PostTypeId] = @__myId_0) AND ([p].[CreationDate] >= ''2013-01-01T00:00:00.000'')',N'@__myId_0 int',@__myId_0=7
然后,我可以在执行计划中看到,使用了相同的查询计划,因为顶部的查询有第一个设置计划的查询,然后第二个使用它并保留了估计的166行,但实际上只返回了4行

另外,如果我查看第二个查询属性,可以确认这一点,并且可以看到它是用6编译的,put是用7运行的


使用变量,而不是值。Haaaaa刚刚尝试过,是的,就是这样,magic知道它是变量而不是值