|
From: <ric...@us...> - 2009-11-19 16:04:51
|
Revision: 4839
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4839&view=rev
Author: ricbrown
Date: 2009-11-19 16:04:43 +0000 (Thu, 19 Nov 2009)
Log Message:
-----------
Added typed inline restrictions to QueryOver.
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs
trunk/nhibernate/src/NHibernate/IQueryOver.cs
trunk/nhibernate/src/NHibernate/NHibernate.csproj
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs
Added Paths:
-----------
trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverRestrictionBuilder.cs
Added: trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverRestrictionBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverRestrictionBuilder.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverRestrictionBuilder.cs 2009-11-19 16:04:43 UTC (rev 4839)
@@ -0,0 +1,169 @@
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+
+using NHibernate.Impl;
+using NHibernate.SqlCommand;
+
+namespace NHibernate.Criterion.Lambda
+{
+
+ public class QueryOverRestrictionBuilder<T> : QueryOverRestrictionBuilderBase<QueryOver<T>, T>
+ {
+
+ public QueryOverRestrictionBuilder(QueryOver<T> root, string propertyName)
+ : base(root, propertyName) { }
+
+ }
+
+ public class IQueryOverRestrictionBuilder<T> : QueryOverRestrictionBuilderBase<IQueryOver<T>, T>
+ {
+
+ public IQueryOverRestrictionBuilder(IQueryOver<T> root, string propertyName)
+ : base(root, propertyName) { }
+
+ }
+
+ public class QueryOverRestrictionBuilderBase<R, T>
+ where R : IQueryOver<T>
+ {
+ public class LambdaBetweenBuilder
+ {
+ private R root;
+ private string propertyName;
+ private object lo;
+
+ public LambdaBetweenBuilder(R root, string propertyName, object lo)
+ {
+ this.root = root;
+ this.propertyName = propertyName;
+ this.lo = lo;
+ }
+
+ public R And(object hi)
+ {
+ return (R)root.And(Restrictions.Between(propertyName, lo, hi));
+ }
+ }
+
+ private R root;
+ private string propertyName;
+
+ /// <summary>
+ /// Constructed with property name
+ /// </summary>
+ public QueryOverRestrictionBuilderBase(R root, string propertyName)
+ {
+ this.root = root;
+ this.propertyName = propertyName;
+ }
+
+ /// <summary>
+ /// Apply a "between" constraint to the named property
+ /// </summary>
+ public LambdaBetweenBuilder IsBetween(object lo)
+ {
+ return new LambdaBetweenBuilder(root, propertyName, lo);
+ }
+
+ /// <summary>
+ /// Apply an "in" constraint to the named property
+ /// </summary>
+ public R IsIn(ICollection values)
+ {
+ return (R)root.And(Restrictions.In(propertyName, values));
+ }
+
+ /// <summary>
+ /// Apply an "in" constraint to the named property
+ /// </summary>
+ public R IsIn(object[] values)
+ {
+ return (R)root.And(Restrictions.In(propertyName, values));
+ }
+
+ /// <summary>
+ /// Apply an "in" constraint to the named property
+ /// </summary>
+ public R IsInG<T>(ICollection<T> values)
+ {
+ return (R)root.And(Restrictions.InG(propertyName, values));
+ }
+
+ /// <summary>
+ /// A case-insensitive "like", similar to Postgres "ilike" operator
+ /// </summary>
+ public R IsInsensitiveLike(object value)
+ {
+ return (R)root.And(Restrictions.InsensitiveLike(propertyName, value));
+ }
+
+ /// <summary>
+ /// A case-insensitive "like", similar to Postgres "ilike" operator
+ /// </summary>
+ public R IsInsensitiveLike(string value, MatchMode matchMode)
+ {
+ return (R)root.And(Restrictions.InsensitiveLike(propertyName, value, matchMode));
+ }
+
+ /// <summary>
+ /// Apply an "is empty" constraint to the named property
+ /// </summary>
+ public R IsEmpty
+ {
+ get { return (R)root.And(Restrictions.IsEmpty(propertyName)); }
+ }
+
+ /// <summary>
+ /// Apply a "not is empty" constraint to the named property
+ /// </summary>
+ public R IsNotEmpty
+ {
+ get { return (R)root.And(Restrictions.IsNotEmpty(propertyName)); }
+ }
+
+ /// <summary>
+ /// Apply an "is null" constraint to the named property
+ /// </summary>
+ public R IsNull
+ {
+ get { return (R)root.And(Restrictions.IsNull(propertyName)); }
+ }
+
+ /// <summary>
+ /// Apply an "not is null" constraint to the named property
+ /// </summary>
+ public R IsNotNull
+ {
+ get { return (R)root.And(Restrictions.IsNotNull(propertyName)); }
+ }
+
+ /// <summary>
+ /// Apply a "like" constraint to the named property
+ /// </summary>
+ public R IsLike(object value)
+ {
+ return (R)root.And(Restrictions.Like(propertyName, value));
+ }
+
+ /// <summary>
+ /// Apply a "like" constraint to the named property
+ /// </summary>
+ public R IsLike(string value, MatchMode matchMode)
+ {
+ return (R)root.And(Restrictions.Like(propertyName, value, matchMode));
+ }
+
+ /// <summary>
+ /// Apply a "like" constraint to the named property
+ /// </summary>
+ public R IsLike(string value, MatchMode matchMode, char? escapeChar)
+ {
+ return (R)root.And(Restrictions.Like(propertyName, value, matchMode, escapeChar));
+ }
+
+ }
+
+}
Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-19 14:46:12 UTC (rev 4838)
+++ trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-19 16:04:43 UTC (rev 4839)
@@ -89,6 +89,16 @@
return Add(expression);
}
+ public QueryOverRestrictionBuilder<T> AndRestrictionOn(Expression<Func<T, object>> expression)
+ {
+ return new QueryOverRestrictionBuilder<T>(this, ExpressionProcessor.FindMemberExpression(expression.Body));
+ }
+
+ public QueryOverRestrictionBuilder<T> AndRestrictionOn(Expression<Func<object>> expression)
+ {
+ return new QueryOverRestrictionBuilder<T>(this, ExpressionProcessor.FindMemberExpression(expression.Body));
+ }
+
public QueryOver<T> Where(Expression<Func<T, bool>> expression)
{
return Add(expression);
@@ -104,6 +114,16 @@
return Add(expression);
}
+ public QueryOverRestrictionBuilder<T> WhereRestrictionOn(Expression<Func<T, object>> expression)
+ {
+ return new QueryOverRestrictionBuilder<T>(this, ExpressionProcessor.FindMemberExpression(expression.Body));
+ }
+
+ public QueryOverRestrictionBuilder<T> WhereRestrictionOn(Expression<Func<object>> expression)
+ {
+ return new QueryOverRestrictionBuilder<T>(this, ExpressionProcessor.FindMemberExpression(expression.Body));
+ }
+
public QueryOver<T> Select(params Expression<Func<T, object>>[] projections)
{
List<IProjection> projectionList = new List<IProjection>();
@@ -457,6 +477,12 @@
IQueryOver<T> IQueryOver<T>.And(ICriterion expression)
{ return And(expression); }
+ IQueryOverRestrictionBuilder<T> IQueryOver<T>.AndRestrictionOn(Expression<Func<T, object>> expression)
+ { return new IQueryOverRestrictionBuilder<T>(this, ExpressionProcessor.FindMemberExpression(expression.Body)); }
+
+ IQueryOverRestrictionBuilder<T> IQueryOver<T>.AndRestrictionOn(Expression<Func<object>> expression)
+ { return new IQueryOverRestrictionBuilder<T>(this, ExpressionProcessor.FindMemberExpression(expression.Body)); }
+
IQueryOver<T> IQueryOver<T>.Where(Expression<Func<T, bool>> expression)
{ return Where(expression); }
@@ -466,6 +492,12 @@
IQueryOver<T> IQueryOver<T>.Where(ICriterion expression)
{ return Where(expression); }
+ IQueryOverRestrictionBuilder<T> IQueryOver<T>.WhereRestrictionOn(Expression<Func<T, object>> expression)
+ { return new IQueryOverRestrictionBuilder<T>(this, ExpressionProcessor.FindMemberExpression(expression.Body)); }
+
+ IQueryOverRestrictionBuilder<T> IQueryOver<T>.WhereRestrictionOn(Expression<Func<object>> expression)
+ { return new IQueryOverRestrictionBuilder<T>(this, ExpressionProcessor.FindMemberExpression(expression.Body)); }
+
IQueryOver<T> IQueryOver<T>.Select(params Expression<Func<T, object>>[] projections)
{ return Select(projections); }
Modified: trunk/nhibernate/src/NHibernate/IQueryOver.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/IQueryOver.cs 2009-11-19 14:46:12 UTC (rev 4838)
+++ trunk/nhibernate/src/NHibernate/IQueryOver.cs 2009-11-19 16:04:43 UTC (rev 4839)
@@ -50,6 +50,20 @@
IQueryOver<T> And(ICriterion expression);
/// <summary>
+ /// Add restriction to a property
+ /// </summary>
+ /// <param name="expression">Lambda expression containing path to property</param>
+ /// <returns>criteria instance</returns>
+ IQueryOverRestrictionBuilder<T> AndRestrictionOn(Expression<Func<T, object>> expression);
+
+ /// <summary>
+ /// Add restriction to a property
+ /// </summary>
+ /// <param name="expression">Lambda expression containing path to property</param>
+ /// <returns>criteria instance</returns>
+ IQueryOverRestrictionBuilder<T> AndRestrictionOn(Expression<Func<object>> expression);
+
+ /// <summary>
/// Identical semantics to Add() to allow more readable queries
/// </summary>
/// <param name="expression">Lambda expression</param>
@@ -69,6 +83,20 @@
IQueryOver<T> Where(ICriterion expression);
/// <summary>
+ /// Identical semantics to AndRestrictionOn() to allow more readable queries
+ /// </summary>
+ /// <param name="expression">Lambda expression</param>
+ /// <returns>criteria instance</returns>
+ IQueryOverRestrictionBuilder<T> WhereRestrictionOn(Expression<Func<T, object>> expression);
+
+ /// <summary>
+ /// Identical semantics to AndRestrictionOn() to allow more readable queries
+ /// </summary>
+ /// <param name="expression">Lambda expression</param>
+ /// <returns>criteria instance</returns>
+ IQueryOverRestrictionBuilder<T> WhereRestrictionOn(Expression<Func<object>> expression);
+
+ /// <summary>
/// Add projection expressed as a lambda expression
/// </summary>
/// <param name="projections">Lambda expressions</param>
Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-19 14:46:12 UTC (rev 4838)
+++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-19 16:04:43 UTC (rev 4839)
@@ -512,6 +512,7 @@
<Compile Include="Criterion\Lambda\QueryOverJoinBuilder.cs" />
<Compile Include="Criterion\Lambda\QueryOverLockBuilder.cs" />
<Compile Include="Criterion\Lambda\QueryOverOrderBuilder.cs" />
+ <Compile Include="Criterion\Lambda\QueryOverRestrictionBuilder.cs" />
<Compile Include="Criterion\Lambda\QueryOverSubqueryBuilder.cs" />
<Compile Include="Criterion\Lambda\QueryOverSubqueryPropertyBuilder.cs" />
<Compile Include="Dialect\MsSql2008Dialect.cs" />
Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2009-11-19 14:46:12 UTC (rev 4838)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2009-11-19 16:04:43 UTC (rev 4839)
@@ -105,6 +105,68 @@
AssertCriteriaAreEqual(expected, actual);
}
+ [Test]
+ public void SqlOperatorsInline()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person), "personAlias")
+ .Add(Restrictions.Between("Age", 18, 65))
+ .Add(Restrictions.Between("personAlias.Age", 18, 65))
+ .Add(Restrictions.In("Name", new string[] { "name1", "name2", "name3" }))
+ .Add(Restrictions.In("personAlias.Name", new ArrayList() { "name1", "name2", "name3" }))
+ .Add(Restrictions.InG<int>("Age", new int[] { 1, 2, 3 }))
+ .Add(Restrictions.InsensitiveLike("Name", "test"))
+ .Add(Restrictions.InsensitiveLike("Name", "tEsT", MatchMode.Anywhere))
+ .Add(Restrictions.IsEmpty("Children"))
+ .Add(Restrictions.IsNotEmpty("Children"))
+ .Add(Restrictions.IsNotNull("Name"))
+ .Add(Restrictions.IsNull("Name"))
+ .Add(Restrictions.Like("Name", "%test%"))
+ .Add(Restrictions.Like("Name", "test", MatchMode.Anywhere))
+ .Add(Restrictions.Like("Name", "test", MatchMode.Anywhere, '?'));
+
+ Person personAlias = null;
+ var actual =
+ CreateTestQueryOver<Person>(() => personAlias)
+ .WhereRestrictionOn(p => p.Age).IsBetween(18).And(65)
+ .WhereRestrictionOn(() => personAlias.Age).IsBetween(18).And(65)
+ .AndRestrictionOn(p => p.Name).IsIn(new string[] { "name1", "name2", "name3" })
+ .AndRestrictionOn(() => personAlias.Name).IsIn(new ArrayList() { "name1", "name2", "name3" })
+ .AndRestrictionOn(p => p.Age).IsInG<int>(new int[] { 1, 2, 3 })
+ .AndRestrictionOn(p => p.Name).IsInsensitiveLike("test")
+ .AndRestrictionOn(p => p.Name).IsInsensitiveLike("tEsT", MatchMode.Anywhere)
+ .AndRestrictionOn(p => p.Children).IsEmpty
+ .AndRestrictionOn(p => p.Children).IsNotEmpty
+ .AndRestrictionOn(p => p.Name).IsNotNull
+ .AndRestrictionOn(p => p.Name).IsNull
+ .AndRestrictionOn(p => p.Name).IsLike("%test%")
+ .AndRestrictionOn(p => p.Name).IsLike("test", MatchMode.Anywhere)
+ .AndRestrictionOn(p => p.Name).IsLike("test", MatchMode.Anywhere, '?');
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
+ [Test]
+ public void DetachedRestrictions()
+ {
+ DetachedCriteria expected =
+ DetachedCriteria.For<Person>("personAlias")
+ .Add(Restrictions.Between("Age", 18, 65))
+ .Add(Restrictions.Between("personAlias.Age", 18, 65))
+ .Add(Restrictions.In("Name", new string[] { "name1", "name2", "name3" }))
+ .Add(Restrictions.In("personAlias.Name", new ArrayList() { "name1", "name2", "name3" }));
+
+ Person personAlias = null;
+ QueryOver<Person> actual =
+ new QueryOver<Person>(() => personAlias)
+ .WhereRestrictionOn(p => p.Age).IsBetween(18).And(65)
+ .WhereRestrictionOn(() => personAlias.Age).IsBetween(18).And(65)
+ .AndRestrictionOn(p => p.Name).IsIn(new string[] { "name1", "name2", "name3" })
+ .AndRestrictionOn(() => personAlias.Name).IsIn(new ArrayList() { "name1", "name2", "name3" });
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
}
}
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|