Skip to content

Commit ddba860

Browse files
committed
Improvement to projection list syntax in QueryOver.
(Thanks to maciejk for suggesting improvement in NH-Forge blog reply) SVN: trunk@4921
1 parent 0fa21f4 commit ddba860

File tree

5 files changed

+36
-47
lines changed

5 files changed

+36
-47
lines changed

src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs

+4-7
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,7 @@ public void SubQuery()
231231

232232
QueryOver<Child> averageChildAge =
233233
QueryOver.Of<Child>()
234-
.SelectList
235-
.SelectAvg(c => c.Age)
236-
.EndSelect;
234+
.Select(p => p.SelectAvg(c => c.Age));
237235

238236
QueryOver<Child> childCountQuery =
239237
QueryOver.Of<Child>()
@@ -243,11 +241,10 @@ public void SubQuery()
243241
var nameAndChildCount =
244242
s.QueryOver<Person>(() => personAlias)
245243
.WithSubquery.Where(p => p.Age <= averageChildAge.As<int>())
246-
.SelectList
244+
.Select(list => list
247245
.Select(p => p.Name)
248-
.SelectSubQuery(childCountQuery).WithAlias(() => childCountAlias)
249-
.EndSelect
250-
.OrderBy(() => childCountAlias).Desc
246+
.SelectSubQuery(childCountQuery).WithAlias(() => childCountAlias))
247+
.OrderBy(() => childCountAlias).Desc
251248
.List<object[]>()
252249
.Select(props => new {
253250
Name = (string)props[0],

src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs

+2-3
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ public void InlineProjectionList()
114114
Person personAgeProjectionAlias = null;
115115
var actual =
116116
CreateTestQueryOver<Person>(() => personAlias)
117-
.SelectList
117+
.Select(list => list
118118
.SelectAvg(p => p.Age).WithAlias(() => personAgeProjectionAlias)
119119
.Select(Projections.Avg("Age")) // allows private properties
120120
.SelectAvg(() => personAlias.Age)
@@ -132,8 +132,7 @@ public void InlineProjectionList()
132132
.Select(() => personAlias.Age)
133133
.SelectSubQuery(DetachedQueryOverAge)
134134
.SelectSum(p => p.Age)
135-
.SelectSum(() => personAlias.Age)
136-
.EndSelect;
135+
.SelectSum(() => personAlias.Age));
137136

138137
AssertCriteriaAreEqual(expected, actual);
139138
}

src/NHibernate/Criterion/Lambda/QueryOverProjectionBuilder.cs

+23-31
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,14 @@
99
namespace NHibernate.Criterion.Lambda
1010
{
1111

12-
public class QueryOverProjectionBuilder<TReturn, TRoot, TSubType>
12+
public class QueryOverProjectionBuilder<T>
1313
{
1414

15-
private TReturn fluentReturn;
16-
private IQueryOver<TRoot,TSubType> criteria;
1715
private ProjectionList projectionList;
1816
private IProjection lastProjection = null;
1917

20-
public QueryOverProjectionBuilder(TReturn fluentReturn, IQueryOver<TRoot,TSubType> criteria)
18+
public QueryOverProjectionBuilder()
2119
{
22-
this.fluentReturn = fluentReturn;
23-
this.criteria = criteria;
2420
projectionList = Projections.ProjectionList();
2521
}
2622

@@ -36,23 +32,19 @@ private void PushProjection(IProjection projection)
3632
lastProjection = projection;
3733
}
3834

39-
/// <summary>
40-
/// Create the ProjectionList and return to the query
41-
/// </summary>
42-
public TReturn EndSelect
35+
internal ProjectionList ProjectionList
4336
{
4437
get
4538
{
4639
AddLastProjection();
47-
criteria.Select(projectionList);
48-
return fluentReturn;
40+
return projectionList;
4941
}
5042
}
5143

5244
/// <summary>
5345
/// Create an alias for the previous projection
5446
/// </summary>
55-
public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> WithAlias(Expression<Func<object>> alias)
47+
public QueryOverProjectionBuilder<T> WithAlias(Expression<Func<object>> alias)
5648
{
5749
string aliasContainer = ExpressionProcessor.FindMemberExpression(alias.Body);
5850
lastProjection = Projections.Alias(lastProjection, aliasContainer);
@@ -62,7 +54,7 @@ public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> WithAlias(Expression
6254
/// <summary>
6355
/// Select an arbitrary projection
6456
/// </summary>
65-
public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> Select(IProjection projection)
57+
public QueryOverProjectionBuilder<T> Select(IProjection projection)
6658
{
6759
PushProjection(projection);
6860
return this;
@@ -71,7 +63,7 @@ public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> Select(IProjection p
7163
/// <summary>
7264
/// A property average value
7365
/// </summary>
74-
public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectAvg(Expression<Func<TSubType, object>> expression)
66+
public QueryOverProjectionBuilder<T> SelectAvg(Expression<Func<T, object>> expression)
7567
{
7668
PushProjection(Projections.Avg(expression));
7769
return this;
@@ -80,7 +72,7 @@ public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectAvg(Expression
8072
/// <summary>
8173
/// A property average value
8274
/// </summary>
83-
public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectAvg(Expression<Func<object>> expression)
75+
public QueryOverProjectionBuilder<T> SelectAvg(Expression<Func<object>> expression)
8476
{
8577
PushProjection(Projections.Avg(expression));
8678
return this;
@@ -89,7 +81,7 @@ public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectAvg(Expression
8981
/// <summary>
9082
/// A property value count
9183
/// </summary>
92-
public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectCount(Expression<Func<TSubType, object>> expression)
84+
public QueryOverProjectionBuilder<T> SelectCount(Expression<Func<T, object>> expression)
9385
{
9486
PushProjection(Projections.Count(expression));
9587
return this;
@@ -98,7 +90,7 @@ public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectCount(Expressi
9890
/// <summary>
9991
/// A property value count
10092
/// </summary>
101-
public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectCount(Expression<Func<object>> expression)
93+
public QueryOverProjectionBuilder<T> SelectCount(Expression<Func<object>> expression)
10294
{
10395
PushProjection(Projections.Count(expression));
10496
return this;
@@ -107,7 +99,7 @@ public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectCount(Expressi
10799
/// <summary>
108100
/// A distinct property value count
109101
/// </summary>
110-
public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectCountDistinct(Expression<Func<TSubType, object>> expression)
102+
public QueryOverProjectionBuilder<T> SelectCountDistinct(Expression<Func<T, object>> expression)
111103
{
112104
PushProjection(Projections.CountDistinct(expression));
113105
return this;
@@ -116,7 +108,7 @@ public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectCountDistinct(
116108
/// <summary>
117109
/// A distinct property value count
118110
/// </summary>
119-
public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectCountDistinct(Expression<Func<object>> expression)
111+
public QueryOverProjectionBuilder<T> SelectCountDistinct(Expression<Func<object>> expression)
120112
{
121113
PushProjection(Projections.CountDistinct(expression));
122114
return this;
@@ -125,7 +117,7 @@ public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectCountDistinct(
125117
/// <summary>
126118
/// A grouping property value
127119
/// </summary>
128-
public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectGroup(Expression<Func<TSubType, object>> expression)
120+
public QueryOverProjectionBuilder<T> SelectGroup(Expression<Func<T, object>> expression)
129121
{
130122
PushProjection(Projections.Group(expression));
131123
return this;
@@ -134,7 +126,7 @@ public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectGroup(Expressi
134126
/// <summary>
135127
/// A grouping property value
136128
/// </summary>
137-
public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectGroup(Expression<Func<object>> expression)
129+
public QueryOverProjectionBuilder<T> SelectGroup(Expression<Func<object>> expression)
138130
{
139131
PushProjection(Projections.Group(expression));
140132
return this;
@@ -143,7 +135,7 @@ public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectGroup(Expressi
143135
/// <summary>
144136
/// A property maximum value
145137
/// </summary>
146-
public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectMax(Expression<Func<TSubType, object>> expression)
138+
public QueryOverProjectionBuilder<T> SelectMax(Expression<Func<T, object>> expression)
147139
{
148140
PushProjection(Projections.Max(expression));
149141
return this;
@@ -152,7 +144,7 @@ public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectMax(Expression
152144
/// <summary>
153145
/// A property maximum value
154146
/// </summary>
155-
public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectMax(Expression<Func<object>> expression)
147+
public QueryOverProjectionBuilder<T> SelectMax(Expression<Func<object>> expression)
156148
{
157149
PushProjection(Projections.Max(expression));
158150
return this;
@@ -161,7 +153,7 @@ public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectMax(Expression
161153
/// <summary>
162154
/// A property minimum value
163155
/// </summary>
164-
public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectMin(Expression<Func<TSubType, object>> expression)
156+
public QueryOverProjectionBuilder<T> SelectMin(Expression<Func<T, object>> expression)
165157
{
166158
PushProjection(Projections.Min(expression));
167159
return this;
@@ -170,7 +162,7 @@ public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectMin(Expression
170162
/// <summary>
171163
/// A property minimum value
172164
/// </summary>
173-
public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectMin(Expression<Func<object>> expression)
165+
public QueryOverProjectionBuilder<T> SelectMin(Expression<Func<object>> expression)
174166
{
175167
PushProjection(Projections.Min(expression));
176168
return this;
@@ -179,7 +171,7 @@ public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectMin(Expression
179171
/// <summary>
180172
/// A projected property value
181173
/// </summary>
182-
public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> Select(Expression<Func<TSubType, object>> expression)
174+
public QueryOverProjectionBuilder<T> Select(Expression<Func<T, object>> expression)
183175
{
184176
PushProjection(Projections.Property(expression));
185177
return this;
@@ -188,13 +180,13 @@ public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> Select(Expression<Fu
188180
/// <summary>
189181
/// A projected property value
190182
/// </summary>
191-
public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> Select(Expression<Func<object>> expression)
183+
public QueryOverProjectionBuilder<T> Select(Expression<Func<object>> expression)
192184
{
193185
PushProjection(Projections.Property(expression));
194186
return this;
195187
}
196188

197-
public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectSubQuery<U>(QueryOver<U> detachedQueryOver)
189+
public QueryOverProjectionBuilder<T> SelectSubQuery<U>(QueryOver<U> detachedQueryOver)
198190
{
199191
PushProjection(Projections.SubQuery(detachedQueryOver));
200192
return this;
@@ -203,7 +195,7 @@ public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectSubQuery<U>(Qu
203195
/// <summary>
204196
/// A property value sum
205197
/// </summary>
206-
public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectSum(Expression<Func<TSubType, object>> expression)
198+
public QueryOverProjectionBuilder<T> SelectSum(Expression<Func<T, object>> expression)
207199
{
208200
PushProjection(Projections.Sum(expression));
209201
return this;
@@ -212,7 +204,7 @@ public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectSum(Expression
212204
/// <summary>
213205
/// A property value sum
214206
/// </summary>
215-
public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectSum(Expression<Func<object>> expression)
207+
public QueryOverProjectionBuilder<T> SelectSum(Expression<Func<object>> expression)
216208
{
217209
PushProjection(Projections.Sum(expression));
218210
return this;

src/NHibernate/Criterion/QueryOver.cs

+5-4
Original file line numberDiff line numberDiff line change
@@ -264,9 +264,10 @@ public QueryOver<TRoot,TSubType> Select(params IProjection[] projections)
264264
return this;
265265
}
266266

267-
public QueryOverProjectionBuilder<QueryOver<TRoot,TSubType>, TRoot, TSubType> SelectList
267+
public QueryOver<TRoot, TSubType> Select(Func<QueryOverProjectionBuilder<TSubType>, QueryOverProjectionBuilder<TSubType>> list)
268268
{
269-
get { return new QueryOverProjectionBuilder<QueryOver<TRoot,TSubType>, TRoot, TSubType>(this, this); }
269+
criteria.SetProjection(list(new QueryOverProjectionBuilder<TSubType>()).ProjectionList);
270+
return this;
270271
}
271272

272273
public QueryOverOrderBuilder<TRoot,TSubType> OrderBy(Expression<Func<TSubType, object>> path)
@@ -604,8 +605,8 @@ IQueryOver<TRoot,TSubType> IQueryOver<TRoot,TSubType>.Select(params Expression<F
604605
IQueryOver<TRoot,TSubType> IQueryOver<TRoot,TSubType>.Select(params IProjection[] projections)
605606
{ return Select(projections); }
606607

607-
QueryOverProjectionBuilder<IQueryOver<TRoot,TSubType>, TRoot, TSubType> IQueryOver<TRoot,TSubType>.SelectList
608-
{ get { return new QueryOverProjectionBuilder<IQueryOver<TRoot,TSubType>,TRoot,TSubType>(this, this); } }
608+
IQueryOver<TRoot, TSubType> IQueryOver<TRoot, TSubType>.Select(Func<QueryOverProjectionBuilder<TSubType>, QueryOverProjectionBuilder<TSubType>> list)
609+
{ return Select(list); }
609610

610611
IQueryOverOrderBuilder<TRoot,TSubType> IQueryOver<TRoot,TSubType>.OrderBy(Expression<Func<TSubType, object>> path)
611612
{ return new IQueryOverOrderBuilder<TRoot,TSubType>(this, path); }

src/NHibernate/IQueryOver.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,9 @@ public interface IQueryOver<TRoot,TSubType> : IQueryOver<TRoot>
208208
IQueryOver<TRoot,TSubType> Select(params IProjection[] projections);
209209

210210
/// <summary>
211-
/// Create a list of projections inline
211+
/// Create a list of projections using a projection builder
212212
/// </summary>
213-
QueryOverProjectionBuilder<IQueryOver<TRoot,TSubType>, TRoot, TSubType> SelectList { get; }
213+
IQueryOver<TRoot, TSubType> Select(Func<QueryOverProjectionBuilder<TSubType>, QueryOverProjectionBuilder<TSubType>> list);
214214

215215
/// <summary>
216216
/// Add order expressed as a lambda expression

0 commit comments

Comments
 (0)