Is there a query generator or extension point for QueryOver, for example, for LINQ?

I am trying to use the calculated properties that I use with Query<T>() inside QueryOver<T>() . When using the LINQ query, I can register my own generators with a custom DefaultLinqToHqlGeneratorsRegistry . This works great for computed properties from an expression , so the code is not duplicated.

I cannot find an extension point for registering custom generators for the QueryOver API. He exists?

I would not want to duplicate the calculated property logic inside the raw SQL string ( Map(x => x.Prop).Formula("query").LazyLoad().Access.ReadOnly() ). This means that there are twice as much logic and twice as many tests.

From what I saw through the source , the QueryOver API uses Criterion as its base ... which directly translates to raw SQL, rather than HQL.

+4
source share
2 answers

Linq and QueryOver use different paths for sql:

 QueryOver -> Expression -> Criteria \ Linq -> LinqParser -> Hql --> Sql 

for criteria there is NHibernate.Impl.ExpressionProcessor.RegisterCustomMethodCall(...); which may be what you want.

A simple example:

 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)); } } 

Remember to call Register (). After that, you can use it as follows:

 session.QueryOver<Order>().Where(o => o.Date.Month() == DateTime.Today.Month).List(); 
+3
source

A simple example:

 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)); } } 

Remember to call Register (). After that, you can use it as follows:

 session.QueryOver<Order>().Where(o => o.Date.Month() == DateTime.Today.Month).List(); 
0
source

All Articles