gpt4 book ai didi

linq - 编写自定义 NHibernate HQL 生成器时如何访问参数属性

转载 作者:行者123 更新时间:2023-12-01 04:30:58 27 4
gpt4 key购买 nike

我有以下自定义类型,上面有一个方法来确定一个时间跨度是否与另一个时间跨度重叠

public struct DateTimeSpan
{
public DateTime? Start { get; set; }
public DateTime? End { get; set; }

public bool Overlaps(DateTimeSpan overlap)
{
//....
}
}

我正在尝试编写自定义 HQL 生成器,以便当我在数据访问 LINQ 查询中使用此方法时,它会在查询数据库时生成适当的 SQL。

这是我的 BaseHqlGeneratorForMethod 的开始试图比较 End一个属性(property)DateTimeSpan与另一个

public class DateSpanOverlapsDateTimeSpanHqlGenerator : BaseHqlGeneratorForMethod
{
public DateSpanOverlapsDateTimeSpanHqlGenerator()
{
SupportedMethods = new[]
{
ReflectionHelper.GetMethodDefinition<DateTimeSpan>(x => x.Overlaps(new DateTimeSpan()))
};
}

public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder builder, IHqlExpressionVisitor visitor)
{
var endTargetProperty = ReflectionHelper.GetProperty<DateTimeSpan, DateTime?>(x => x.End);
Expression endTargetExpression = Expression.MakeMemberAccess(targetObject, endTargetProperty);

var endArgumentProperty = ReflectionHelper.GetProperty<DateTimeSpan, DateTime?>(x => x.End);
Expression endArgumentExpression = Expression.MakeMemberAccess(arguments[0], endArgumentProperty);

return builder.GreaterThanOrEqual(visitor.Visit(endTargetExpression).AsExpression(), visitor.Visit(endArgumentExpression).AsExpression());
}
}

我已经证明 End targetObject中的属性(property)评估正常,但无论我做什么,我都无法评估 End属性(property) arguments[0] .上面的代码只是我尝试过的一个例子(而且看起来最明显,因为它适用于 targetObject )我尝试的大多数事情都以异常 Antlr.Runtime.NoViableAltException 结束。

targetObject 之间的明显区别和 arguments[0]是那个targetObject类型为 PropertyExpressionarguments[0]类型为 ConstantExpression .我认为这意味着需要有不同的方式来访问它们,但我不知道它是什么!

最佳答案

treeBuilder.Constant(arg.SubProperty);将缓存您的对象,因此您在运行查询时最终会遇到问题。

您应该在 DateTimeSpan 中添加一个重载

public bool Overlaps(DateTime? start, DateTime? end)

将签名匹配到您的 DateSpanOverlapsDateTimeSpanHqlGenerator

SupportedMethods = new[]
{
ReflectionHelper.GetMethodDefinition<DateTimeSpan>(span => span.Overlaps(default(DateTime?), default(DateTime?)))
};

并以这种方式获取值:

public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder builder, IHqlExpressionVisitor visitor)
{
var startProperty = ReflectionHelper.GetProperty<DateTimeSpan, DateTime?>(x => x.Start);
var endProperty = ReflectionHelper.GetProperty<DateTimeSpan, DateTime?>(x => x.End);

MemberExpression targetStartExpression = Expression.MakeMemberAccess(targetObject, startProperty);
MemberExpression targetEndExpression = Expression.MakeMemberAccess(targetObject, endProperty);

HqlExpression startDateExpression = visitor.Visit(arguments[0]).AsExpression();
HqlExpression endDateExpression = visitor.Visit(arguments[1]).AsExpression();
....
}

之后照常营业:

builder.LessThanOrEqual(visitor.Visit(targetStartExpression).AsExpression(), endDateExpression)

关于linq - 编写自定义 NHibernate HQL 生成器时如何访问参数属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14954110/

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