Linq .NET 5 中的 DatePart 函数使用可变间隔
Posted
技术标签:
【中文标题】Linq .NET 5 中的 DatePart 函数使用可变间隔【英文标题】:DatePart function in Linq .NET 5 using variable interval 【发布时间】:2021-06-19 08:31:39 【问题描述】:对于 EF Core 5,应使用 SqlFunctionExpression 构造来使用 DatePart 函数,如下所示:
public int? DatePart(string datePartArg, DateTime? date) => throw new InvalidOperationException($"nameof(DatePart) cannot be called client side.");
protected override void OnModelCreating(ModelBuilder builder)
var methodInfo = typeof(DbFunctionExtensions).GetMethod(nameof(DatePart));
var datePartMethodInfo = typeof(NotificationDbContext) // Your DB Context
.GetRuntimeMethod(nameof(NotificationDbContext.DatePart), new[] typeof(string), typeof(DateTime) );
builder.HasDbFunction(datePartMethodInfo)
.HasTranslation(args =>
new SqlFunctionExpression("DATEPART",
new[]
new SqlFragmentExpression((args.ToArray()[0] as SqlConstantExpression).Value.ToString()),
args.ToArray()[1]
,
true,
new[] false, false ,
typeof(int?),
null
)
);
以后我们可以这样称呼它
_context.DatePart("day", x.Date);
但是我们如何传递变量而不是像下面这样的静态“天”
string daysInterval="day";
_context.DatePart(daysInterval, x.Date);
daysInterval 将由基于条件返回年、月或日的函数初始化。那么我们如何一般地传递 daysInterval 而不是硬编码呢?
【问题讨论】:
【参考方案1】:我认为这是不可能的,因为 DATEPART 的第一个参数无法参数化。 EG SQL 看起来像:
select datepart(day,getdate())
不是
select datepart('day',getdate())
还有这个查询
_context.DatePart(daysInterval, x.Date);
将使用daysInterval
的参数进行翻译。 AFAIK 要做到这一点,您是否必须转换查询表达式并用文字表达式动态替换变量表达式,这是太多的工作。
或者提供您自己的 TSQL 标量函数,该函数将 varchar 作为第一个参数。喜欢
create function datepart2(@interval varchar(20), @d datetime2)
returns int
as
begin
if @interval = 'day'
return datepart(day,@d)
else if @interval = 'second'
return datepart(second,@d)
--. . .
return -1
end
并像这样注册它:
modelBuilder.HasDbFunction(datePartMethodInfo)
.HasTranslation(args =>
new SqlFunctionExpression("dbo.DATEPART2",
new[]
args.ToArray()[0],
args.ToArray()[1]
,
true,
new[] false, false ,
typeof(int?),
null
)
);
【讨论】:
以上是关于Linq .NET 5 中的 DatePart 函数使用可变间隔的主要内容,如果未能解决你的问题,请参考以下文章