作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在尝试在 Entity Framework 中执行窗口函数时遇到了一些麻烦。 (有问题的项目建立在 EF 上,但会从在 SQL Server 上计算 PERCENTILE_DISC 获得很多 yield 。)
我正在创建一个新的约定并将其添加到对象模型中,以便将对某个方法的调用转换为执行 PERCENT_DISC 窗口函数的 SQL。
创建的 EdmFunction 的 CommandText 为:
PERCENTILE_DISC (0.8) WITHIN GROUP (ORDER BY o.ExpectedPayment) OVER (PARTITION BY o.OrderType)
var medians = context.Set<UserLocation>().Select(x => CustomFunction.Percentile()).ToList();
System.Data.Entity.Core.EntityCommandCompilationException:
'An error occurred while preparing definition of the function 'ConsoleApp5.Percentile'. See the inner exception for details.'
Inner Exception:
EntitySqlException: The query syntax is not valid. Near identifier 'WITHIN', line 1, column 35.
var p80s = context.Database.SqlQuery<decimal>("SELECT DISTINCT PERCENTILE_DISC (0.8) WITHIN GROUP (ORDER BY o.ExpectedPayment) OVER (PARTITION BY o.OrderType) from Orders o").ToList();
最佳答案
我在一个项目中工作,该项目使用一个拦截器来注册慢查询。
下面,我放上拦截器的代码:
using System;
using System.Data.Common;
using System.Data.Entity.Infrastructure.Interception;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace Nash.Data.Interceptors.SlowQuery
{
public sealed class SqlQueryCommandInterceptor : IDbCommandInterceptor
{
private readonly ISlowQueryLogger _slowQueryLogger;
public SqlQueryCommandInterceptor(ISlowQueryLogger slowQueryLogger)
{
_slowQueryLogger = slowQueryLogger;
}
public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
=> interceptionContext.UserState = Stopwatch.StartNew();
public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
=> LogSlowQuery(interceptionContext, command);
public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
=> interceptionContext.UserState = Stopwatch.StartNew();
public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
=> LogSlowQuery(interceptionContext, command);
public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
=> interceptionContext.UserState = Stopwatch.StartNew();
public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
=> LogSlowQuery(interceptionContext, command);
private void LogSlowQuery<T>(DbCommandInterceptionContext<T> interceptionContext, DbCommand dbCommand)
{
var debugText = GetDbCommandDebugText(dbCommand);
var userState = (Stopwatch)interceptionContext.UserState;
userState.Stop();
var elapsed = userState.Elapsed;
if (elapsed > TimeSpan.FromSeconds(2.6))
_slowQueryLogger.LogSlowQuery(debugText, elapsed);
}
private static string GetDbCommandDebugText(DbCommand dbCommand)
{
var debugText = dbCommand.CommandText;
if (dbCommand is SqlCommand && debugText.Contains("@"))
{
var matches = Regex.Matches(debugText, @"(\@[\w\.]+)").Cast<Match>().ToArray();
var paramDict = dbCommand.Parameters.Cast<SqlParameter>()
.Select(x => new
{
ParameterName = x.ParameterName.StartsWith("@") ? x.ParameterName : "@" + x.ParameterName,
Value = x.Value,
})
.ToDictionary(x => x.ParameterName, x => x.Value);
var buffer = new StringBuilder();
var i = 0;
foreach (var m in matches)
{
if (m.Index > i)
{
buffer.Append(debugText.Substring(i, m.Index - i));
i = m.Index;
}
var paramName = m.Groups[1].Value;
if (paramDict.TryGetValue(paramName, out var paramVal))
if (paramVal == null || DBNull.Value.Equals(paramVal))
buffer.Append($"NULL");
else
buffer.Append($"'{paramVal}'");
else
buffer.Append(paramName);
i += m.Length;
}
if (i < debugText.Length)
buffer.Append(debugText.Substring(i, debugText.Length - i));
debugText = buffer.ToString();
}
return debugText;
}
}
}
要使用此拦截器,您可以编写如下代码:
using System.Data.Entity.Infrastructure.Interception;
DbInterception.Add(NinjectWebCommon.Kernel.Get<SqlQueryCommandInterceptor>());
就我而言,我将此代码放入我的网络应用程序启动:Global.asax.cs。我使用 Ninject 来获取拦截器的一个实例。
关于entity-framework - 当抛出 EntitySqlException 时,我可以看到正在进行的 SQL,或者我可以覆盖 EntityCommandCompilationException 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56535365/
我在使用 EntityConnection 时收到此错误,我不知道如何解决。使用 ObjectContext 时,我可以设置属性 DefaultContainerName 并且它可以工作,但现在我不知
我在尝试在 Entity Framework 中执行窗口函数时遇到了一些麻烦。 (有问题的项目建立在 EF 上,但会从在 SQL Server 上计算 PERCENTILE_DISC 获得很多 yie
我不得不更改查询中一个参数的数据类型,现在我收到了此消息标题中概述的错误消息。我一直试图弄清楚问题出在哪里,我唯一能想到的是,由于查询的一个参数是一个数字,另一个是字符串,所以这是导致问题的原因。不幸
我是一名优秀的程序员,十分优秀!