From: <ric...@us...> - 2009-11-25 18:36:17
|
Revision: 4857 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4857&view=rev Author: ricbrown Date: 2009-11-25 18:36:07 +0000 (Wed, 25 Nov 2009) Log Message: ----------- Added typed inline projections to QueryOver. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/Projections.cs 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/ProjectionsFixture.cs Added Paths: ----------- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverProjectionBuilder.cs Added: trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverProjectionBuilder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverProjectionBuilder.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverProjectionBuilder.cs 2009-11-25 18:36:07 UTC (rev 4857) @@ -0,0 +1,223 @@ + +using System; +using System.Collections.Generic; +using System.Linq.Expressions; + +using NHibernate.Impl; +using NHibernate.SqlCommand; + +namespace NHibernate.Criterion.Lambda +{ + + public class QueryOverProjectionBuilder<R, T> + { + + private R fluentReturn; + private IQueryOver<T> criteria; + private ProjectionList projectionList; + private IProjection lastProjection = null; + + public QueryOverProjectionBuilder(R fluentReturn, IQueryOver<T> criteria) + { + this.fluentReturn = fluentReturn; + this.criteria = criteria; + projectionList = Projections.ProjectionList(); + } + + private void AddLastProjection() + { + if (lastProjection != null) + projectionList.Add(lastProjection); + } + + private void PushProjection(IProjection projection) + { + AddLastProjection(); + lastProjection = projection; + } + + /// <summary> + /// Create the ProjectionList and return to the query + /// </summary> + public R EndSelect + { + get + { + AddLastProjection(); + criteria.Select(projectionList); + return fluentReturn; + } + } + + /// <summary> + /// Create an alias for the previous projection + /// </summary> + public QueryOverProjectionBuilder<R, T> WithAlias(Expression<Func<object>> alias) + { + string aliasContainer = ExpressionProcessor.FindMemberExpression(alias.Body); + lastProjection = Projections.Alias(lastProjection, aliasContainer); + return this; + } + + /// <summary> + /// Select an arbitrary projection + /// </summary> + public QueryOverProjectionBuilder<R, T> Select(IProjection projection) + { + PushProjection(projection); + return this; + } + + /// <summary> + /// A property average value + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectAvg(Expression<Func<T, object>> expression) + { + PushProjection(Projections.Avg(expression)); + return this; + } + + /// <summary> + /// A property average value + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectAvg(Expression<Func<object>> expression) + { + PushProjection(Projections.Avg(expression)); + return this; + } + + /// <summary> + /// A property value count + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectCount(Expression<Func<T, object>> expression) + { + PushProjection(Projections.Count(expression)); + return this; + } + + /// <summary> + /// A property value count + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectCount(Expression<Func<object>> expression) + { + PushProjection(Projections.Count(expression)); + return this; + } + + /// <summary> + /// A distinct property value count + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectCountDistinct(Expression<Func<T, object>> expression) + { + PushProjection(Projections.CountDistinct(expression)); + return this; + } + + /// <summary> + /// A distinct property value count + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectCountDistinct(Expression<Func<object>> expression) + { + PushProjection(Projections.CountDistinct(expression)); + return this; + } + + /// <summary> + /// A grouping property value + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectGroup(Expression<Func<T, object>> expression) + { + PushProjection(Projections.Group(expression)); + return this; + } + + /// <summary> + /// A grouping property value + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectGroup(Expression<Func<object>> expression) + { + PushProjection(Projections.Group(expression)); + return this; + } + + /// <summary> + /// A property maximum value + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectMax(Expression<Func<T, object>> expression) + { + PushProjection(Projections.Max(expression)); + return this; + } + + /// <summary> + /// A property maximum value + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectMax(Expression<Func<object>> expression) + { + PushProjection(Projections.Max(expression)); + return this; + } + + /// <summary> + /// A property minimum value + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectMin(Expression<Func<T, object>> expression) + { + PushProjection(Projections.Min(expression)); + return this; + } + + /// <summary> + /// A property minimum value + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectMin(Expression<Func<object>> expression) + { + PushProjection(Projections.Min(expression)); + return this; + } + + /// <summary> + /// A projected property value + /// </summary> + public QueryOverProjectionBuilder<R, T> Select(Expression<Func<T, object>> expression) + { + PushProjection(Projections.Property(expression)); + return this; + } + + /// <summary> + /// A projected property value + /// </summary> + public QueryOverProjectionBuilder<R, T> Select(Expression<Func<object>> expression) + { + PushProjection(Projections.Property(expression)); + return this; + } + + public QueryOverProjectionBuilder<R, T> SelectSubQuery<U>(QueryOver<U> detachedQueryOver) + { + PushProjection(Projections.SubQuery(detachedQueryOver)); + return this; + } + + /// <summary> + /// A property value sum + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectSum(Expression<Func<T, object>> expression) + { + PushProjection(Projections.Sum(expression)); + return this; + } + + /// <summary> + /// A property value sum + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectSum(Expression<Func<object>> expression) + { + PushProjection(Projections.Sum(expression)); + return this; + } + + } + +} Modified: trunk/nhibernate/src/NHibernate/Criterion/Projections.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/Projections.cs 2009-11-23 18:00:21 UTC (rev 4856) +++ trunk/nhibernate/src/NHibernate/Criterion/Projections.cs 2009-11-25 18:36:07 UTC (rev 4857) @@ -370,7 +370,7 @@ /// <summary> /// A grouping property value /// </summary> - public static PropertyProjection GroupProperty<T>(Expression<Func<T, object>> expression) + public static PropertyProjection Group<T>(Expression<Func<T, object>> expression) { return Projections.GroupProperty(ExpressionProcessor.FindMemberExpression(expression.Body)); } @@ -378,7 +378,7 @@ /// <summary> /// A grouping property value /// </summary> - public static PropertyProjection GroupProperty(Expression<Func<object>> expression) + public static PropertyProjection Group(Expression<Func<object>> expression) { return Projections.GroupProperty(ExpressionProcessor.FindMemberExpression(expression.Body)); } Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-23 18:00:21 UTC (rev 4856) +++ trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-25 18:36:07 UTC (rev 4857) @@ -171,6 +171,11 @@ return this; } + QueryOverProjectionBuilder<QueryOver<T>, T> SelectList + { + get { return new QueryOverProjectionBuilder<QueryOver<T>, T>(this, this); } + } + public QueryOverOrderBuilder<T> OrderBy(Expression<Func<T, object>> path) { return new QueryOverOrderBuilder<T>(this, path); @@ -558,6 +563,9 @@ IQueryOver<T> IQueryOver<T>.Select(params IProjection[] projections) { return Select(projections); } + QueryOverProjectionBuilder<IQueryOver<T>, T> IQueryOver<T>.SelectList + { get { return new QueryOverProjectionBuilder<IQueryOver<T>,T>(this, this); } } + IQueryOverOrderBuilder<T> IQueryOver<T>.OrderBy(Expression<Func<T, object>> path) { return new IQueryOverOrderBuilder<T>(this, path); } Modified: trunk/nhibernate/src/NHibernate/IQueryOver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/IQueryOver.cs 2009-11-23 18:00:21 UTC (rev 4856) +++ trunk/nhibernate/src/NHibernate/IQueryOver.cs 2009-11-25 18:36:07 UTC (rev 4857) @@ -137,6 +137,11 @@ IQueryOver<T> Select(params IProjection[] projections); /// <summary> + /// Create a list of projections inline + /// </summary> + QueryOverProjectionBuilder<IQueryOver<T>, T> SelectList { get; } + + /// <summary> /// Add order expressed as a lambda expression /// </summary> /// <param name="path">Lambda expression</param> Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-23 18:00:21 UTC (rev 4856) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-25 18:36:07 UTC (rev 4857) @@ -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\QueryOverProjectionBuilder.cs" /> <Compile Include="Criterion\Lambda\QueryOverRestrictionBuilder.cs" /> <Compile Include="Criterion\Lambda\QueryOverSubqueryBuilder.cs" /> <Compile Include="Criterion\Lambda\QueryOverSubqueryPropertyBuilder.cs" /> Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs 2009-11-23 18:00:21 UTC (rev 4856) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs 2009-11-25 18:36:07 UTC (rev 4857) @@ -70,8 +70,8 @@ .Add(Projections.Count(() => personAlias.Age)) .Add(Projections.CountDistinct<Person>(p => p.Age)) .Add(Projections.CountDistinct(() => personAlias.Age)) - .Add(Projections.GroupProperty<Person>(p => p.Age)) - .Add(Projections.GroupProperty(() => personAlias.Age)) + .Add(Projections.Group<Person>(p => p.Age)) + .Add(Projections.Group(() => personAlias.Age)) .Add(Projections.Max<Person>(p => p.Age)) .Add(Projections.Max(() => personAlias.Age)) .Add(Projections.Min<Person>(p => p.Age)) @@ -85,6 +85,59 @@ AssertCriteriaAreEqual(expected, actual); } + [Test] + public void InlineProjectionList() + { + ICriteria expected = + CreateTestCriteria(typeof(Person), "personAlias") + .SetProjection(Projections.ProjectionList() + .Add(Projections.Alias(Projections.Avg("Age"), "personAgeProjectionAlias")) + .Add(Projections.Avg("Age")) + .Add(Projections.Avg("personAlias.Age")) + .Add(Projections.Count("Age")) + .Add(Projections.Count("personAlias.Age")) + .Add(Projections.CountDistinct("Age")) + .Add(Projections.CountDistinct("personAlias.Age")) + .Add(Projections.GroupProperty("Age")) + .Add(Projections.GroupProperty("personAlias.Age")) + .Add(Projections.Max("Age")) + .Add(Projections.Max("personAlias.Age")) + .Add(Projections.Min("Age")) + .Add(Projections.Min("personAlias.Age")) + .Add(Projections.Property("Age")) + .Add(Projections.Property("personAlias.Age")) + .Add(Projections.SubQuery(DetachedCriteriaAge)) + .Add(Projections.Sum("Age")) + .Add(Projections.Sum("personAlias.Age"))); + + Person personAlias = null; + Person personAgeProjectionAlias = null; + var actual = + CreateTestQueryOver<Person>(() => personAlias) + .SelectList + .SelectAvg(p => p.Age).WithAlias(() => personAgeProjectionAlias) + .Select(Projections.Avg("Age")) // allows private properties + .SelectAvg(() => personAlias.Age) + .SelectCount(p => p.Age) + .SelectCount(() => personAlias.Age) + .SelectCountDistinct(p => p.Age) + .SelectCountDistinct(() => personAlias.Age) + .SelectGroup(p => p.Age) + .SelectGroup(() => personAlias.Age) + .SelectMax(p => p.Age) + .SelectMax(() => personAlias.Age) + .SelectMin(p => p.Age) + .SelectMin(() => personAlias.Age) + .Select(p => p.Age) + .Select(() => personAlias.Age) + .SelectSubQuery(DetachedQueryOverAge) + .SelectSum(p => p.Age) + .SelectSum(() => personAlias.Age) + .EndSelect; + + 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. |