nfp*_*lee 4 c# linq nhibernate
我正在尝试执行以下LINQ查询.
var tasks = session.Query<Task>()
.Where(t => t.StartDate.DayOfYear == DateTime.UtcNow.DayOfYear)
.ToList();
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为不支持DayOfYear.但是,如果我说:
var tasks = session.Query<Task>()
.Where(t => t.StartDate.Day == DateTime.UtcNow.Day)
.ToList();
Run Code Online (Sandbox Code Playgroud)
它工作正常.所以我决定查看NHibernate源代码,看看他们是如何让它工作的.我在MsSql2000Dialect.cs(MsSql2008Dialect类继承)中找到以下行:
RegisterFunction("day",
new SQLFunctionTemplate(NHibernateUtil.Int32, "datepart(day, ?1)"));
Run Code Online (Sandbox Code Playgroud)
因此,我在构造函数中使用以下行创建了自己的自定义方言(继承自MsSql2008Dialect):
RegisterFunction("dayofyear",
new SQLFunctionTemplate(NHibernateUtil.Int32, "datepart(dy, ?1)"));
Run Code Online (Sandbox Code Playgroud)
然后在我的配置中注册了自定义方言,但我仍然收到以下错误:
NHibernate.QueryException:无法解析属性: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());
}
}
Run Code Online (Sandbox Code Playgroud)
然后我们需要在某个地方注册这个新的发电机.NHibernate使用DefaultLinqToHqlGeneratorsRegistry.让我们扩展这个类:
public class ExtendedLinqToHqlGeneratorsRegistry : DefaultLinqToHqlGeneratorsRegistry
{
public ExtendedLinqToHqlGeneratorsRegistry()
{
this.Merge(new DateTimeDayOfYearPropertyHqlGenerator());
}
}
Run Code Online (Sandbox Code Playgroud)
最后,我们需要告诉NHibernate使用扩展注册表而不是默认注册表.如果您正在使用Loquacious配置,请执行以下操作:
config.LinqToHqlGeneratorsRegistry<ExtendedLinqToHqlGeneratorsRegistry>();
Run Code Online (Sandbox Code Playgroud)
或者,如果您正在使用FluentNHibernate:
...
.ExposeConfiguration(cfg =>
cfg.SetProperty(NHibernate.Cfg.Environment.LinqToHqlGeneratorsRegistry,
typeof(ExtendedLinqToHqlGeneratorsRegistry).AssemblyQualifiedName))
Run Code Online (Sandbox Code Playgroud)
这应该工作了!
| 归档时间: |
|
| 查看次数: |
729 次 |
| 最近记录: |