gpt4 book ai didi

c# - NHibernate - DateTime.DayOfYear LINQ

转载 作者:太空狗 更新时间:2023-10-30 00:32:08 25 4
gpt4 key购买 nike

我正在尝试执行以下 LINQ 查询。

var tasks = session.Query<Task>()
.Where(t => t.StartDate.DayOfYear == DateTime.UtcNow.DayOfYear)
.ToList();

这不起作用,因为不支持 DayOfYear。但是,如果我说:

var tasks = session.Query<Task>()
.Where(t => t.StartDate.Day == DateTime.UtcNow.Day)
.ToList();

它工作正常。所以我决定查看 NHibernate 源代码,看看他们是如何让它工作的。我在 MsSql2000Dialect.cs(MsSql2008Dialect 类继承)中找到了以下行:

RegisterFunction("day",
new SQLFunctionTemplate(NHibernateUtil.Int32, "datepart(day, ?1)"));

因此,我在构造函数中使用以下行创建了自己的自定义方言(继承自 MsSql2008Dialect):

RegisterFunction("dayofyear",
new SQLFunctionTemplate(NHibernateUtil.Int32, "datepart(dy, ?1)"));

然后在我的配置中注册了自定义方言,但我仍然收到以下错误:

NHibernate.QueryException: could not resolve property: DayOfYear

如果有人能告诉我我做错了什么,我将不胜感激。谢谢

最佳答案

你已经完成了一半的工作。

您已经告诉 NHibernate 如何将 HQL dayofyear() 方法调用转换为 SQL Server 方言,但您没有告诉如何将 LINQ 表达式转换为 HQL。基本上您需要扩展 LINQ 提供程序。让我们开始吧!

首先,我们需要实现一个新的IHqlGeneratorForProperty。只需以这种方式扩展 BaseHqlGeneratorForProperty:

public class DateTimeDayOfYearPropertyHqlGenerator : NHibernate.Linq.Functions.BaseHqlGeneratorForProperty
{
public DateTimeDayOfYearPropertyHqlGenerator()
{
SupportedProperties = new[]
{
ReflectionHelper.GetProperty((DateTime x) => x.DayOfYear)
};
}

public override NHibernate.Hql.Ast.HqlTreeNode BuildHql(MemberInfo member, Expression expression, NHibernate.Hql.Ast.HqlTreeBuilder treeBuilder, NHibernate.Linq.Visitors.IHqlExpressionVisitor visitor)
{
return treeBuilder.MethodCall("dayofyear", visitor.Visit(expression).AsExpression());
}
}

然后我们需要在某个地方注册这个新的生成器。NHibernate 使用 DefaultLinqToHqlGeneratorsRegistry。让我们扩展这个类:

public class ExtendedLinqToHqlGeneratorsRegistry : DefaultLinqToHqlGeneratorsRegistry
{
public ExtendedLinqToHqlGeneratorsRegistry()
{
this.Merge(new DateTimeDayOfYearPropertyHqlGenerator());
}
}

最后,我们需要告诉 NHibernate 使用扩展注册表而不是默认注册表。如果您使用的是 Loquacious 配置,只需执行以下操作:

config.LinqToHqlGeneratorsRegistry<ExtendedLinqToHqlGeneratorsRegistry>();

或者,如果您使用的是 FluentNHibernate:

...
.ExposeConfiguration(cfg =>
cfg.SetProperty(NHibernate.Cfg.Environment.LinqToHqlGeneratorsRegistry,
typeof(ExtendedLinqToHqlGeneratorsRegistry).AssemblyQualifiedName))

现在应该可以了!

关于c# - NHibernate - DateTime.DayOfYear LINQ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19835381/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com