目標は、NHibernateとLinqを使用して次のようなことを行うことです。
Session.Query<MyClass>().Where(x => x.DateGreaterThen(DateTime.Now))
この例は少し単純化されていますが、Where述語でMyClassメソッドを呼び出したいという考え方です。したがって、MyClassは次のようになります。
public class MyClass
{
public static readonly Expression<Func<MyClass, DateTime, bool>> GreaterThenExpression =
(x, dt) => x.MyDateTimeProperty > dt.Date;
private static readonly Func<MyClass, DateTime, bool> GreaterThenFunc = GreaterThenExpression.Compile();
public Guid Id { get; set; }
public DateTime MyDateTimeProperty { get; set; }
public bool DateGreaterThen(DateTime dt)
{
return GreaterThenFunc(this, dt);
}
}
カスタムジェネレーター:
public class EntityMethodGenerator<T1, T2, TResult> : BaseHqlGeneratorForMethod
{
private Expression<Func<T1, T2, TResult>> _returnValueExpression;
public EntityMethodGenerator()
{
SupportedMethods = new[]
{
ReflectionHelper.GetMethodDefinition<MyClass>(myClass => myClass.DateGreaterThen(DateTime.Now))
};
}
public static void Register(ILinqToHqlGeneratorsRegistry registry, Expression<Action<T1>> method, Expression<Func<T1, T2, TResult>> returnValueExpression)
{
var generator = new EntityMethodGenerator<T1, T2, TResult> { _returnValueExpression = returnValueExpression };
registry.RegisterGenerator(ReflectionHelper.GetMethodDefinition(method), generator);
}
public override HqlTreeNode BuildHql(
MethodInfo method,
Expression targetObject,
ReadOnlyCollection<Expression> arguments,
HqlTreeBuilder treeBuilder,
IHqlExpressionVisitor visitor)
{
return visitor.Visit(_returnValueExpression);
}
}
そして最後に、カスタムカスタムジェネレータレジストリ:
public class OwnLinqToHqlGeneratorsRegistry : DefaultLinqToHqlGeneratorsRegistry
{
public OwnLinqToHqlGeneratorsRegistry()
{
EntityMethodGenerator<MyClass, DateTime, bool>.Register(this, (myClass) => myClass.DateGreaterThen(DateTime.Now), MyClass.GreaterThenExpression);
}
}
しかし、これは機能していませSystem.Data.SqlClient.SqlException : Invalid column name 'dt'.
ん。BuildHqlメソッドが正しく実装されていないのではないかと疑っています。これを修正するのに役立ちますか?
ちなみに、メソッドGreaterThenExpression
でHqlTreeを手動で構築するのではなく、ジェネレーターで式を使用したいと思います。BuildHql