3

ある期間が別の期間と重複するかどうかを判断するためのメソッドを含む次のカスタムタイプがあります

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

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

カスタムHQLジェネレーターを作成しようとしています。これにより、データアクセスLINQクエリ内でこのメソッドを使用すると、データベースのクエリ時に適切なSQLが生成されます。

これは、一方のプロパティをもう一方のプロパティと比較しようとする私の始まりBaseHqlGeneratorForMethodですEndDateTimeSpan

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が、何をしても、のEndプロパティを評価することはできませんarguments[0]。上記のコードは、私が試したもののほんの一例です(そして、それがで機能することを考えると、最も明白なようですtargetObject)。Antlr.Runtime.NoViableAltException

targetObjectとの明らかな違いの1つarguments[0]targetObject、タイプPropertyExpressionarguments[0]タイプConstantExpressionです。これは、それらにアクセスするためのさまざまな方法が必要であることを意味すると思いますが、それが何であるかを理解することはできません!

4

2 に答える 2

2

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)
于 2014-03-06T11:28:06.713 に答える