LINQ和QueryOver採取不同的路徑到SQL:
QueryOver -> Expression -> Criteria \
Linq -> LinqParser -> Hql --> Sql
的標準有NHibernate.Impl.ExpressionProcessor.RegisterCustomMethodCall(...);
這可能是你想要的。
一個簡單的例子:
public static class QueryOverExtensions
{
public static void Register()
{
ExpressionProcessor.RegisterCustomProjection(() => QueryOverExtensions.Day(default(DateTime)), QueryOverExtensions.ProcessDay);
ExpressionProcessor.RegisterCustomProjection(() => QueryOverExtensions.Month(default(DateTime)), QueryOverExtensions.ProcessMonth);
ExpressionProcessor.RegisterCustomProjection(() => QueryOverExtensions.Year(default(DateTime)), QueryOverExtensions.ProcessYear);
}
public static Int32 Day(this DateTime dateTimeProperty)
{
return (dateTimeProperty.Day);
}
public static Int32 Month(this DateTime dateTimeProperty)
{
return (dateTimeProperty.Month);
}
public static Int32 Year(this DateTime dateTimeProperty)
{
return (dateTimeProperty.Year);
}
private static IProjection ProcessDay(MethodCallExpression methodCallExpression)
{
IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]).AsProjection();
return (Projections.SqlFunction("day", NHibernateUtil.Int32, property));
}
private static IProjection ProcessMonth(MethodCallExpression methodCallExpression)
{
IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]).AsProjection();
return (Projections.SqlFunction("month", NHibernateUtil.Int32, property));
}
private static IProjection ProcessYear(MethodCallExpression methodCallExpression)
{
IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]).AsProjection();
return (Projections.SqlFunction("year", NHibernateUtil.Int32, property));
}
}
不要忘記調用註冊()。之後,你可以使用它像這樣:
session.QueryOver<Order>().Where(o => o.Date.Month() == DateTime.Today.Month).List();
是的我發現這只是在通過源代碼查看時的另一個晚上。最大的問題是它需要一個單獨的'Expression'到'ICriteria'處理器。我會看到我想出的,然後讓你知道。 – TheCloudlessSky 2013-05-06 11:34:06