是否有强制实体框架发送date
参数以匹配列数据类型?这导致我们的一些查询中的密钥查找非常昂贵。
示例生成的查询在几分钟内运行,我从SQL Server探查器中抓取:
exec sp_executesql N'SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT(1) AS [A1]
FROM [table] AS [Extent1]
WHERE ( EXISTS (SELECT
1 AS [C1]
FROM [search] AS [Extent2]
WHERE ([Extent1].[Number] = [Extent2].[Number]) AND ([Extent2].[SearchInstance] = @p__linq__0)
)) AND ([Extent1].[Date] >= @p__linq__1) AND ([Extent1].[Date] <= @p__linq__2)
) AS [GroupBy1]',N'@p__linq__0 uniqueidentifier,@p__linq__1 datetime2(7),@p__linq__2 datetime2(7)',@p__linq__0='1A530478-17F8-442E-B718-32049086717F',@p__linq__1='2012-07-24',@p__linq__2='2015-07-24'
如果我手动更改日期参数的类型,则此查询将在0秒内执行。
exec sp_executesql N'SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT(1) AS [A1]
FROM [table] AS [Extent1]
WHERE ( EXISTS (SELECT
1 AS [C1]
FROM [search] AS [Extent2]
WHERE ([Extent1].[Number] = [Extent2].[Number]) AND ([Extent2].[SearchInstance] = @p__linq__0)
)) AND ([Extent1].[Date] >= @p__linq__1) AND ([Extent1].[Date] <= @p__linq__2)
) AS [GroupBy1]',N'@p__linq__0 uniqueidentifier,@p__linq__1 date,@p__linq__2 date',@p__linq__0='1A530478-17F8-442E-B718-32049086717F',@p__linq__1='2012-07-24',@p__linq__2='2015-07-24'
使用ef codefirst,我指定.HasColumType("date")
但未更改正在发送的参数类型。
**表名和表格列已被更改以保护无辜。
答案 0 :(得分:1)
粗略地说,使用DbInterceptor。
using System.Data;
using System.Data.Common;
using System.Data.Entity.Infrastructure.Interception;
using System.Data.SqlClient;
using System.Linq;
public static class SomewhereDoThis
{
public static void Register()
{
DbInterception.Add(new DateInterceptor());
}
}
public class DateInterceptor : IDbCommandInterceptor
{
/* .. */
public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
ShrinkDates(command);
}
public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
ShrinkDates(command);
}
public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext interceptionContext)
{
ShrinkDates(command);
}
public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
ShrinkDates(command);
}
private static void ShrinkDates(DbCommand command)
{
command.Parameters
.OfType<SqlParameter>()
.Where(p => p.SqlDbType == SqlDbType.DateTime2)
.Where(p => p.Value != DBNull.Value)
.Where(p => p.Value is DateTime)
.Where(p => ((DateTime)p.Value).TimeOfDay == TimeSpan.Zero)
.ToList()
.ForEach(p => p.SqlDbType = SqlDbType.Date);
}
}