From: <ric...@us...> - 2009-11-07 12:43:19
|
Revision: 4823 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4823&view=rev Author: ricbrown Date: 2009-11-07 12:43:07 +0000 (Sat, 07 Nov 2009) Log Message: ----------- Fleshed out Subquery overloads for QueryOver. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryBuilder.cs trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryPropertyBuilder.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/Model.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-06 22:50:19 UTC (rev 4822) +++ trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-07 12:43:07 UTC (rev 4823) @@ -66,7 +66,7 @@ /// Method to allow comparison of detached query in Lambda expression /// e.g., p => p.Name == myQuery.As<string> /// </summary> - /// <typeparam name="T">type returned by query</typeparam> + /// <typeparam name="R">type returned by query</typeparam> /// <returns>throws an exception if evaluated directly at runtime.</returns> public R As<R>() { Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryBuilder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryBuilder.cs 2009-11-06 22:50:19 UTC (rev 4822) +++ trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryBuilder.cs 2009-11-07 12:43:07 UTC (rev 4823) @@ -51,9 +51,14 @@ public S WhereProperty(Expression<Func<T, object>> expression) { string property = ExpressionProcessor.FindMemberExpression(expression.Body); - return (S) new S().Set(root, property); + return (S)new S().Set(root, property, null); } + public S WhereValue(object value) + { + return (S)new S().Set(root, null, value); + } + } } Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryPropertyBuilder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryPropertyBuilder.cs 2009-11-06 22:50:19 UTC (rev 4822) +++ trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryPropertyBuilder.cs 2009-11-07 12:43:07 UTC (rev 4823) @@ -29,7 +29,7 @@ { protected QueryOverSubqueryPropertyBuilderBase() { } - public abstract QueryOverSubqueryPropertyBuilderBase Set(object root, string path); + internal abstract QueryOverSubqueryPropertyBuilderBase Set(object root, string path, object value); } public class QueryOverSubqueryPropertyBuilderBase<R, T> : QueryOverSubqueryPropertyBuilderBase @@ -38,28 +38,115 @@ protected R root; protected string path; + protected object value; protected QueryOverSubqueryPropertyBuilderBase() { } - public override QueryOverSubqueryPropertyBuilderBase Set(object root, string path) + internal override QueryOverSubqueryPropertyBuilderBase Set(object root, string path, object value) { this.root = (R)root; this.path = path; + this.value = value; return this; } + private void AddSubquery<U>( + Func<string, DetachedCriteria, AbstractCriterion> propertyMethod, + Func<object, DetachedCriteria, AbstractCriterion> valueMethod, + QueryOver<U> detachedCriteria) + { + if (path != null) + { + root.And(propertyMethod(path, detachedCriteria.DetachedCriteria)); + } + else + { + root.And(valueMethod(value, detachedCriteria.DetachedCriteria)); + } + } + /// <summary> /// Add a property equal subquery criterion /// </summary> /// <param name="detachedCriteria">detached subquery</param> - public R Eq(QueryOver<T> detachedCriteria) + public R Eq<U>(QueryOver<U> detachedCriteria) { - root.Where(Subqueries.PropertyEq(path, detachedCriteria.DetachedCriteria)); + AddSubquery(Subqueries.PropertyEq, Subqueries.Eq, detachedCriteria); return root; } + /// <summary> + /// Create a property greater than or equal subquery criterion + /// </summary> + /// <param name="detachedCriteria">detached subquery</param> + public R Ge<U>(QueryOver<U> detachedCriteria) + { + AddSubquery(Subqueries.PropertyGe, Subqueries.Ge, detachedCriteria); + return root; + } + + /// <summary> + /// Create a property greater than subquery criterion + /// </summary> + /// <param name="detachedCriteria">detached subquery</param> + public R Gt<U>(QueryOver<U> detachedCriteria) + { + AddSubquery(Subqueries.PropertyGt, Subqueries.Gt, detachedCriteria); + return root; + } + + /// <summary> + /// Create a property in subquery criterion + /// </summary> + /// <param name="detachedCriteria">detached subquery</param> + public R In<U>(QueryOver<U> detachedCriteria) + { + AddSubquery(Subqueries.PropertyIn, Subqueries.In, detachedCriteria); + return root; + } + + /// <summary> + /// Create a property less than or equal subquery criterion + /// </summary> + /// <param name="detachedCriteria">detached subquery</param> + public R Le<U>(QueryOver<U> detachedCriteria) + { + AddSubquery(Subqueries.PropertyLe, Subqueries.Le, detachedCriteria); + return root; + } + + /// <summary> + /// Create a property less than subquery criterion + /// </summary> + /// <param name="detachedCriteria">detached subquery</param> + public R Lt<U>(QueryOver<U> detachedCriteria) + { + AddSubquery(Subqueries.PropertyLt, Subqueries.Lt, detachedCriteria); + return root; + } + + /// <summary> + /// Create a property not equal subquery criterion + /// </summary> + /// <param name="detachedCriteria">detached subquery</param> + public R Ne<U>(QueryOver<U> detachedCriteria) + { + AddSubquery(Subqueries.PropertyNe, Subqueries.Ne, detachedCriteria); + return root; + } + + /// <summary> + /// Create a property not in subquery criterion + /// </summary> + /// <param name="detachedCriteria">detached subquery</param> + public R NotIn<U>(QueryOver<U> detachedCriteria) + { + AddSubquery(Subqueries.PropertyNotIn, Subqueries.NotIn, detachedCriteria); + return root; + } + } } Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/Model.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/Model.cs 2009-11-06 22:50:19 UTC (rev 4822) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/Model.cs 2009-11-07 12:43:07 UTC (rev 4823) @@ -35,6 +35,7 @@ { public virtual int Id { get; set; } public virtual string Nickname { get; set; } + public virtual int Age { get; set; } } public class Relation Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs 2009-11-06 22:50:19 UTC (rev 4822) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs 2009-11-07 12:43:07 UTC (rev 4823) @@ -16,13 +16,13 @@ public class SubqueryFixture : LambdaFixtureBase { - private Person _subqueryPersonAlias = null; + private Child _subqueryChildAlias = null; - private DetachedCriteria DetachedCriteriaPerson + private DetachedCriteria DetachedCriteriaChild { get { - return ToDetachedCriteria(DetachedQueryOverPerson); + return ToDetachedCriteria(DetachedQueryOverChild); } } @@ -34,37 +34,70 @@ } } - private QueryOver<Person> DetachedQueryOverPerson + private DetachedCriteria DetachedCriteriaAge { get { + return ToDetachedCriteria(DetachedQueryOverAge); + } + } + + private QueryOver<Child> DetachedQueryOverChild + { + get + { return - new QueryOver<Person>(() => _subqueryPersonAlias) - .Where(() => _subqueryPersonAlias.Name == "subquery name"); + new QueryOver<Child>(() => _subqueryChildAlias) + .Where(() => _subqueryChildAlias.Nickname == "subquery name"); } } - private QueryOver<Person> DetachedQueryOverName + private QueryOver<Child> DetachedQueryOverName { get { return - new QueryOver<Person>(() => _subqueryPersonAlias) - .Where(() => _subqueryPersonAlias.Name == "subquery name") - .Select(p => p.Name); + new QueryOver<Child>(() => _subqueryChildAlias) + .Where(() => _subqueryChildAlias.Nickname == "subquery name") + .Select(p => p.Nickname); } } + private QueryOver<Child> DetachedQueryOverAge + { + get + { + return + new QueryOver<Child>(() => _subqueryChildAlias) + .Where(() => _subqueryChildAlias.Nickname == "subquery name") + .Select(p => p.Age); + } + } + [Test] public void Property() { ICriteria expected = CreateTestCriteria(typeof(Person)) - .Add(Subqueries.PropertyEq("Name", DetachedCriteriaName)); + .Add(Subqueries.PropertyEq("Name", DetachedCriteriaName)) + .Add(Subqueries.PropertyGe("Age", DetachedCriteriaAge)) + .Add(Subqueries.PropertyGt("Age", DetachedCriteriaAge)) + .Add(Subqueries.PropertyIn("Name", DetachedCriteriaName)) + .Add(Subqueries.PropertyLe("Age", DetachedCriteriaAge)) + .Add(Subqueries.PropertyLt("Age", DetachedCriteriaAge)) + .Add(Subqueries.PropertyNe("Name", DetachedCriteriaName)) + .Add(Subqueries.PropertyNotIn("Name", DetachedCriteriaName)); var actual = CreateTestQueryOver<Person>() - .WithSubquery.WhereProperty(p => p.Name).Eq(DetachedQueryOverName); + .WithSubquery.WhereProperty(p => p.Name).Eq(DetachedQueryOverName) + .WithSubquery.WhereProperty(p => p.Age).Ge(DetachedQueryOverAge) + .WithSubquery.WhereProperty(p => p.Age).Gt(DetachedQueryOverAge) + .WithSubquery.WhereProperty(p => p.Name).In(DetachedQueryOverName) + .WithSubquery.WhereProperty(p => p.Age).Le(DetachedQueryOverAge) + .WithSubquery.WhereProperty(p => p.Age).Lt(DetachedQueryOverAge) + .WithSubquery.WhereProperty(p => p.Name).Ne(DetachedQueryOverName) + .WithSubquery.WhereProperty(p => p.Name).NotIn(DetachedQueryOverName); AssertCriteriaAreEqual(expected, actual); } @@ -74,15 +107,53 @@ { ICriteria expected = CreateTestCriteria(typeof(Person)) - .Add(Subqueries.PropertyEq("Name", DetachedCriteriaName)); + .Add(Subqueries.PropertyEq("Name", DetachedCriteriaName)) + .Add(Subqueries.PropertyNe("Name", DetachedCriteriaName)) + .Add(Subqueries.PropertyGe("Age", DetachedCriteriaAge)) + .Add(Subqueries.PropertyGt("Age", DetachedCriteriaAge)) + .Add(Subqueries.PropertyLe("Age", DetachedCriteriaAge)) + .Add(Subqueries.PropertyLt("Age", DetachedCriteriaAge)); var actual = CreateTestQueryOver<Person>() - .WithSubquery.Where(p => p.Name == DetachedQueryOverName.As<string>()); + .WithSubquery.Where(p => p.Name == DetachedQueryOverName.As<string>()) + .WithSubquery.Where(p => p.Name != DetachedQueryOverName.As<string>()) + .WithSubquery.Where(p => p.Age >= DetachedQueryOverAge.As<int>()) + .WithSubquery.Where(p => p.Age > DetachedQueryOverAge.As<int>()) + .WithSubquery.Where(p => p.Age <= DetachedQueryOverAge.As<int>()) + .WithSubquery.Where(p => p.Age < DetachedQueryOverAge.As<int>()); AssertCriteriaAreEqual(expected, actual); } + [Test] + public void Value() + { + ICriteria expected = + CreateTestCriteria(typeof(Person)) + .Add(Subqueries.Eq("Name", DetachedCriteriaName)) + .Add(Subqueries.Ge("Age", DetachedCriteriaAge)) + .Add(Subqueries.Gt("Age", DetachedCriteriaAge)) + .Add(Subqueries.In("Name", DetachedCriteriaName)) + .Add(Subqueries.Le("Age", DetachedCriteriaAge)) + .Add(Subqueries.Lt("Age", DetachedCriteriaAge)) + .Add(Subqueries.Ne("Name", DetachedCriteriaName)) + .Add(Subqueries.NotIn("Name", DetachedCriteriaName)); + + var actual = + CreateTestQueryOver<Person>() + .WithSubquery.WhereValue("Name").Eq(DetachedQueryOverName) + .WithSubquery.WhereValue("Age").Ge(DetachedQueryOverAge) + .WithSubquery.WhereValue("Age").Gt(DetachedQueryOverAge) + .WithSubquery.WhereValue("Name").In(DetachedQueryOverName) + .WithSubquery.WhereValue("Age").Le(DetachedQueryOverAge) + .WithSubquery.WhereValue("Age").Lt(DetachedQueryOverAge) + .WithSubquery.WhereValue("Name").Ne(DetachedQueryOverName) + .WithSubquery.WhereValue("Name").NotIn(DetachedQueryOverName); + + 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. |