Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / System.Data.Entity / System / Data / Common / CommandTrees / RelationalExpressions.cs
1 //---------------------------------------------------------------------
2 // <copyright file="RelationalExpressions.cs" company="Microsoft">
3 //      Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //
6 // @owner  Microsoft
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
9
10 using System;
11 using System.Collections.Generic;
12 using System.Globalization;
13 using System.Diagnostics;
14
15 using System.Data.Common;
16 using System.Data.Metadata.Edm;
17 using System.Data.Common.CommandTrees.Internal;
18
19 namespace System.Data.Common.CommandTrees
20 {
21     /// <summary>
22     /// Represents an apply operation, which is the invocation of the specified functor for each element in the specified input set.
23     /// </summary>
24     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
25     public sealed class DbApplyExpression : DbExpression
26     {
27         private readonly DbExpressionBinding _input;
28         private readonly DbExpressionBinding _apply;
29
30         internal DbApplyExpression(DbExpressionKind applyKind, TypeUsage resultRowCollectionTypeUsage, DbExpressionBinding input, DbExpressionBinding apply)
31             : base(applyKind, resultRowCollectionTypeUsage)
32         {
33             Debug.Assert(input != null, "DbApplyExpression input cannot be null");
34             Debug.Assert(input != null, "DbApplyExpression apply cannot be null");
35             Debug.Assert(DbExpressionKind.CrossApply == applyKind || DbExpressionKind.OuterApply == applyKind, "Invalid DbExpressionKind for DbApplyExpression");
36
37             _input = input;
38             _apply = apply;
39         }
40
41         /// <summary>
42         /// Gets the <see cref="DbExpressionBinding"/> that specifies the functor that is invoked for each element in the input set.
43         /// </summary>
44         public DbExpressionBinding Apply { get { return _apply;  } }
45
46         /// <summary>
47         /// Gets the <see cref="DbExpressionBinding"/> that specifies the input set.
48         /// </summary>
49         public DbExpressionBinding Input { get { return _input; } }
50
51         /// <summary>
52         /// The visitor pattern method for expression visitors that do not produce a result value.
53         /// </summary>
54         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
55         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
56         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
57
58         /// <summary>
59         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
60         /// </summary>
61         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
62         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
63         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
64         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
65         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
66     }
67
68     /// <summary>
69     /// Represents the removal of duplicate elements from the specified set operand.
70     /// </summary>
71     /// <remarks>
72     /// DbDistinctExpression requires that its argument has a collection result type
73     /// with an element type that is equality comparable.
74     /// </remarks>
75     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
76     public sealed class DbDistinctExpression : DbUnaryExpression
77     {
78         internal DbDistinctExpression(TypeUsage resultType, DbExpression argument)
79             : base(DbExpressionKind.Distinct, resultType, argument)
80         {
81             Debug.Assert(TypeSemantics.IsCollectionType(argument.ResultType), "DbDistinctExpression argument must have a collection result type");
82         }
83
84         /// <summary>
85         /// The visitor pattern method for expression visitors that do not produce a result value.
86         /// </summary>
87         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
88         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
89         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
90
91         /// <summary>
92         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
93         /// </summary>
94         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
95         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
96         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
97         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
98         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
99     }
100
101     /// <summary>
102     /// Represents the conversion of the specified set operand to a singleton.
103     /// If the set is empty the conversion will return null, otherwise the conversion will return one of the elements in the set.
104     /// </summary>
105     /// <remarks>
106     /// DbElementExpression requires that its argument has a collection result type
107     /// </remarks>
108     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
109     public sealed class DbElementExpression : DbUnaryExpression
110     {
111         private bool _singlePropertyUnwrapped;
112
113         internal DbElementExpression(TypeUsage resultType, DbExpression argument)
114             : base(DbExpressionKind.Element, resultType, argument)
115         {
116             this._singlePropertyUnwrapped = false;
117         }
118
119         internal DbElementExpression(TypeUsage resultType, DbExpression argument, bool unwrapSingleProperty)
120             : base(DbExpressionKind.Element, resultType, argument)
121         {
122             this._singlePropertyUnwrapped = unwrapSingleProperty;
123         }
124
125         /// <summary>
126         /// Is the result type of the element equal to the result type of the single property 
127         /// of the element of its operand?
128         /// </summary>
129         internal bool IsSinglePropertyUnwrapped { get { return _singlePropertyUnwrapped; } }
130
131         /// <summary>
132         /// The visitor pattern method for expression visitors that do not produce a result value.
133         /// </summary>
134         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
135         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
136         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
137
138         /// <summary>
139         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
140         /// </summary>
141         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
142         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
143         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
144         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
145         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
146     }
147
148     /// <summary>
149     /// Represents the set subtraction operation between the left and right operands.
150     /// </summary>
151     /// <remarks>
152     /// DbExceptExpression requires that its arguments have a common collection result type
153     /// </remarks>
154     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
155     public sealed class DbExceptExpression : DbBinaryExpression
156     {
157         internal DbExceptExpression(TypeUsage resultType, DbExpression left, DbExpression right)
158             : base(DbExpressionKind.Except, resultType, left, right)
159         {
160             Debug.Assert(object.ReferenceEquals(resultType, left.ResultType), "DbExceptExpression result type should be result type of left argument");
161         }
162
163         /// <summary>
164         /// The visitor pattern method for expression visitors that do not produce a result value.
165         /// </summary>
166         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
167         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
168         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
169
170         /// <summary>
171         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
172         /// </summary>
173         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
174         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
175         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
176         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
177         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
178     }
179
180     /// <summary>
181     /// Represents a predicate applied to an input set to produce the set of elements that satisfy the predicate.
182     /// </summary>
183     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
184     public sealed class DbFilterExpression : DbExpression
185     {
186         private readonly DbExpressionBinding _input;
187         private readonly DbExpression _predicate;
188
189         internal DbFilterExpression(TypeUsage resultType, DbExpressionBinding input, DbExpression predicate)
190             : base(DbExpressionKind.Filter, resultType)
191         {
192             Debug.Assert(input != null, "DbFilterExpression input cannot be null");
193             Debug.Assert(predicate != null, "DbBFilterExpression predicate cannot be null");
194             Debug.Assert(TypeSemantics.IsPrimitiveType(predicate.ResultType, PrimitiveTypeKind.Boolean), "DbFilterExpression predicate must have a Boolean result type");
195             
196             _input = input;
197             _predicate = predicate;
198         }
199
200         /// <summary>
201         /// Gets the <see cref="DbExpressionBinding"/> that specifies the input set.
202         /// </summary>
203         public DbExpressionBinding Input { get { return _input; } }
204         
205         /// <summary>
206         /// Gets the <see cref="DbExpression"/> that specifies the predicate used to filter the input set.
207         /// </summary>
208         public DbExpression Predicate { get { return _predicate; } }
209
210         /// <summary>
211         /// The visitor pattern method for expression visitors that do not produce a result value.
212         /// </summary>
213         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
214         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
215         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
216
217         /// <summary>
218         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
219         /// </summary>
220         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
221         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
222         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
223         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
224         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
225     }
226
227     /// <summary>
228     /// Represents a group by operation, which is a grouping of the elements in the input set based on the specified key expressions followed by the application of the specified aggregates.
229     /// </summary>
230     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
231     public sealed class DbGroupByExpression : DbExpression
232     {
233         private readonly DbGroupExpressionBinding _input;
234         private readonly DbExpressionList _keys;
235         private readonly System.Collections.ObjectModel.ReadOnlyCollection<DbAggregate> _aggregates;
236
237         internal DbGroupByExpression(TypeUsage collectionOfRowResultType,
238                                      DbGroupExpressionBinding input,
239                                      DbExpressionList groupKeys,
240                                      System.Collections.ObjectModel.ReadOnlyCollection<DbAggregate> aggregates)
241             : base(DbExpressionKind.GroupBy, collectionOfRowResultType)
242         {
243             Debug.Assert(input != null, "DbGroupExpression input cannot be null");
244             Debug.Assert(groupKeys != null, "DbGroupExpression keys cannot be null");
245             Debug.Assert(aggregates != null, "DbGroupExpression aggregates cannot be null");
246             Debug.Assert(groupKeys.Count > 0 || aggregates.Count > 0, "At least one key or aggregate is required");
247
248             _input = input;
249             _keys = groupKeys;
250             _aggregates = aggregates;
251         }
252
253         /// <summary>
254         /// Gets the <see cref="DbGroupExpressionBinding"/> that specifies the input set and provides access to the set element and group element variables.
255         /// </summary>
256         public DbGroupExpressionBinding Input { get { return _input; } }
257
258         /// <summary>
259         /// Gets an <see cref="DbExpression"/> list that provides grouping keys.
260         /// </summary>
261         public IList<DbExpression> Keys { get { return _keys; } }
262
263         /// <summary>
264         /// Gets an <see cref="DbAggregate"/> list that provides the aggregates to apply.
265         /// </summary>
266         public IList<DbAggregate> Aggregates { get { return _aggregates; } }
267
268         /// <summary>
269         /// The visitor pattern method for expression visitors that do not produce a result value.
270         /// </summary>
271         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
272         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
273         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
274
275         /// <summary>
276         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
277         /// </summary>
278         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
279         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
280         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
281         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
282         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
283     }
284
285     /// <summary>
286     /// Represents the set intersection operation between the left and right operands.
287     /// </summary>
288     /// <remarks>
289     /// DbIntersectExpression requires that its arguments have a common collection result type
290     /// </remarks>
291     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
292     public sealed class DbIntersectExpression : DbBinaryExpression
293     {
294         internal DbIntersectExpression(TypeUsage resultType, DbExpression left, DbExpression right)
295             : base(DbExpressionKind.Intersect, resultType, left, right)
296         {
297         }
298
299         /// <summary>
300         /// The visitor pattern method for expression visitors that do not produce a result value.
301         /// </summary>
302         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
303         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
304         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
305
306         /// <summary>
307         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
308         /// </summary>
309         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
310         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
311         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
312         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
313         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
314     }
315     
316     /// <summary>
317     /// Represents an unconditional join operation between the given collection arguments
318     /// </summary>
319     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
320     public sealed class DbCrossJoinExpression : DbExpression
321     {
322         private readonly System.Collections.ObjectModel.ReadOnlyCollection<DbExpressionBinding> _inputs;
323
324         internal DbCrossJoinExpression(TypeUsage collectionOfRowResultType, System.Collections.ObjectModel.ReadOnlyCollection<DbExpressionBinding> inputs)
325             : base(DbExpressionKind.CrossJoin, collectionOfRowResultType)
326        {
327            Debug.Assert(inputs != null, "DbCrossJoin inputs cannot be null");
328            Debug.Assert(inputs.Count >= 2, "DbCrossJoin requires at least two inputs");
329
330            _inputs = inputs;
331         }
332         
333         /// <summary>
334         /// Gets an <see cref="DbExpressionBinding"/> list that provide the input sets to the join.
335         /// </summary>
336         public IList<DbExpressionBinding> Inputs { get { return _inputs; } }
337
338         /// <summary>
339         /// The visitor pattern method for expression visitors that do not produce a result value.
340         /// </summary>
341         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
342         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
343         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
344
345         /// <summary>
346         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
347         /// </summary>
348         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
349         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
350         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
351         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
352         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
353     }
354    
355     /// <summary>
356     /// Represents an inner, left outer or full outer join operation between the given collection arguments on the specified join condition.
357     /// </summary>
358     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
359     public sealed class DbJoinExpression : DbExpression
360     {
361         private readonly DbExpressionBinding _left;
362         private readonly DbExpressionBinding _right;
363         private readonly DbExpression _condition;
364
365         internal DbJoinExpression(DbExpressionKind joinKind, TypeUsage collectionOfRowResultType, DbExpressionBinding left, DbExpressionBinding right, DbExpression condition)
366             : base(joinKind, collectionOfRowResultType)
367         {
368             Debug.Assert(left != null, "DbJoinExpression left cannot be null");
369             Debug.Assert(right != null, "DbJoinExpression right cannot be null");
370             Debug.Assert(condition != null, "DbJoinExpression condition cannot be null");
371             Debug.Assert(DbExpressionKind.InnerJoin == joinKind ||
372                          DbExpressionKind.LeftOuterJoin == joinKind ||
373                          DbExpressionKind.FullOuterJoin == joinKind,
374                          "Invalid DbExpressionKind specified for DbJoinExpression");
375
376             _left = left;
377             _right = right;
378             _condition = condition;
379         }
380         
381         /// <summary>
382         /// Gets the <see cref="DbExpressionBinding"/> provides the left input.
383         /// </summary>
384         public DbExpressionBinding Left { get { return _left; } }
385
386         /// <summary>
387         /// Gets the <see cref="DbExpressionBinding"/> provides the right input.
388         /// </summary>
389         public DbExpressionBinding Right { get { return _right; } }
390                 
391         /// <summary>
392         /// Gets the <see cref="DbExpression"/> that defines the join condition to apply.
393         /// </summary>
394         public DbExpression JoinCondition { get { return _condition; } }
395         
396         /// <summary>
397         /// The visitor pattern method for expression visitors that do not produce a result value.
398         /// </summary>
399         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
400         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
401         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
402
403         /// <summary>
404         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
405         /// </summary>
406         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
407         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
408         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
409         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
410         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
411     }
412
413     /// <summary>
414     /// Represents the restriction of the number of elements in the Argument collection to the specified Limit value.
415     /// </summary>
416     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
417     public sealed class DbLimitExpression : DbExpression
418     {
419         private readonly DbExpression _argument;
420         private readonly DbExpression _limit;
421         private readonly bool _withTies;
422
423         internal DbLimitExpression(TypeUsage resultType, DbExpression argument, DbExpression limit, bool withTies)
424             : base(DbExpressionKind.Limit, resultType)
425         {
426             Debug.Assert(argument != null, "DbLimitExpression argument cannot be null");
427             Debug.Assert(limit != null, "DbLimitExpression limit cannot be null");
428             Debug.Assert(object.ReferenceEquals(resultType, argument.ResultType), "DbLimitExpression result type must be the result type of the argument");
429                         
430             this._argument = argument;
431             this._limit = limit;
432             this._withTies = withTies;
433         }
434
435         /// <summary>
436         /// Gets the expression that specifies the input collection.
437         /// </summary>
438         public DbExpression Argument { get { return this._argument; } }
439         
440         /// <summary>
441         /// Gets the expression that specifies the limit on the number of elements returned from the input collection.
442         /// </summary>
443         public DbExpression Limit { get { return this._limit; } }
444         
445         /// <summary>
446         /// Gets whether the limit operation will include tied results, which could produce more results than specifed by the Limit value if ties are present.
447         /// </summary>
448         public bool WithTies { get { return _withTies; } }
449
450         /// <summary>
451         /// The visitor pattern method for expression visitors that do not produce a result value.
452         /// </summary>
453         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
454         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
455         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
456
457         /// <summary>
458         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
459         /// </summary>
460         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
461         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
462         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
463         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
464         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
465     }
466
467     /// <summary>
468     /// Represents the projection of a given set of values over the specified input set.
469     /// </summary>
470     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
471     public sealed class DbProjectExpression : DbExpression
472     {
473         private readonly DbExpressionBinding _input;
474         private readonly DbExpression _projection;
475
476         internal DbProjectExpression(TypeUsage resultType, DbExpressionBinding input, DbExpression projection)
477             : base(DbExpressionKind.Project, resultType)
478         {
479             Debug.Assert(input != null, "DbProjectExpression input cannot be null");
480             Debug.Assert(projection != null, "DbProjectExpression projection cannot be null");
481
482             this._input = input;
483             this._projection = projection;
484         }
485
486         /// <summary>
487         /// Gets the <see cref="DbExpressionBinding"/> that specifies the input set.
488         /// </summary>
489         public DbExpressionBinding Input { get { return _input; } }
490         
491         /// <summary>
492         /// Gets the <see cref="DbExpression"/> that defines the projection.
493         /// </summary>
494         public DbExpression Projection { get { return _projection; } }
495
496         /// <summary>
497         /// The visitor pattern method for expression visitors that do not produce a result value.
498         /// </summary>
499         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
500         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
501         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
502
503         /// <summary>
504         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
505         /// </summary>
506         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
507         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
508         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
509         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
510         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
511     }
512
513     /// <summary>
514     /// Represents a quantifier operation of the specified kind (Any, All) over the elements of the specified input set.
515     /// </summary>
516     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
517     public sealed class DbQuantifierExpression : DbExpression
518     {
519         private readonly DbExpressionBinding _input;
520         private readonly DbExpression _predicate;
521
522         internal DbQuantifierExpression(DbExpressionKind kind, TypeUsage booleanResultType, DbExpressionBinding input, DbExpression predicate)
523             : base(kind, booleanResultType)
524         {
525             Debug.Assert(input != null, "DbQuantifierExpression input cannot be null");
526             Debug.Assert(predicate != null, "DbQuantifierExpression predicate cannot be null");
527             Debug.Assert(TypeSemantics.IsPrimitiveType(booleanResultType, PrimitiveTypeKind.Boolean), "DbQuantifierExpression must have a Boolean result type");
528             Debug.Assert(TypeSemantics.IsPrimitiveType(predicate.ResultType, PrimitiveTypeKind.Boolean), "DbQuantifierExpression predicate must have a Boolean result type");
529
530             this._input = input;
531             this._predicate = predicate;
532         }
533
534         /// <summary>
535         /// Gets the <see cref="DbExpressionBinding"/> that specifies the input set.
536         /// </summary>
537         public DbExpressionBinding Input { get { return _input; } }
538
539         /// <summary>
540         /// Gets the Boolean predicate that should be evaluated for each element in the input set.
541         /// </summary>
542         public DbExpression Predicate { get { return _predicate; } }
543
544         /// <summary>
545         /// The visitor pattern method for expression visitors that do not produce a result value.
546         /// </summary>
547         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
548         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
549         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
550
551         /// <summary>
552         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
553         /// </summary>
554         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
555         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
556         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
557         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
558         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
559     }
560
561     /// <summary>
562     /// Specifies a sort key that can be used as part of the sort order in a DbSortExpression.
563     /// </summary>
564     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
565     public sealed class DbSortClause
566     {
567         private readonly DbExpression _expr;
568         private readonly bool _asc;
569         private readonly string _coll;
570
571         internal DbSortClause(DbExpression key, bool asc, string collation)
572         {
573             Debug.Assert(key != null, "DbSortClause key cannot be null");
574                         
575             _expr = key;            
576             _asc = asc;
577             _coll = collation;
578         }
579
580         /// <summary>
581         /// Gets a Boolean value indicating whether or not this sort key is sorted ascending.
582         /// </summary>
583         public bool Ascending { get { return _asc; } }
584         
585         /// <summary>
586         /// Gets a string value that specifies the collation for this sort key.
587         /// </summary>
588         public string Collation { get { return _coll; } }
589
590         /// <summary>
591         /// Gets the <see cref="DbExpression"/> that provides the value for this sort key.
592         /// </summary>
593         public DbExpression Expression { get { return _expr; } }
594     }
595
596     /// <summary>
597     /// Represents a skip operation of the specified number of elements of the input set after the ordering described in the given sort keys is applied.
598     /// </summary>
599     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
600     public sealed class DbSkipExpression : DbExpression
601     {
602         private readonly DbExpressionBinding _input;
603         private readonly System.Collections.ObjectModel.ReadOnlyCollection<DbSortClause> _keys;
604         private readonly DbExpression _count;
605
606         internal DbSkipExpression(TypeUsage resultType, DbExpressionBinding input, System.Collections.ObjectModel.ReadOnlyCollection<DbSortClause> sortOrder, DbExpression count)
607             : base(DbExpressionKind.Skip, resultType)
608         {
609             Debug.Assert(input != null, "DbSkipExpression input cannot be null");
610             Debug.Assert(sortOrder != null, "DbSkipExpression sort order cannot be null");
611             Debug.Assert(count != null, "DbSkipExpression count cannot be null");
612             Debug.Assert(TypeSemantics.IsCollectionType(resultType), "DbSkipExpression requires a collection result type");
613
614             this._input = input;
615             this._keys = sortOrder;
616             this._count = count;
617         }
618
619         /// <summary>
620         /// Gets the <see cref="DbExpressionBinding"/> that specifies the input set.
621         /// </summary>
622         public DbExpressionBinding Input { get { return _input; } }
623
624         /// <summary>
625         /// Gets a <see cref="DbSortClause"/> list that defines the sort order.
626         /// </summary>
627         public IList<DbSortClause> SortOrder { get { return _keys; } }
628
629         /// <summary>
630         /// Gets the expression that specifies the number of elements from the input collection to skip.
631         /// </summary>
632         public DbExpression Count
633         {
634             get { return _count; } 
635         }
636
637         /// <summary>
638         /// The visitor pattern method for expression visitors that do not produce a result value.
639         /// </summary>
640         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
641         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
642         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
643
644         /// <summary>
645         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
646         /// </summary>
647         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
648         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
649         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
650         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
651         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
652     }
653
654     /// <summary>
655     /// Represents a sort operation applied to the elements of the specified input set based on the given sort keys.
656     /// </summary>
657     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
658     public sealed class DbSortExpression : DbExpression
659     {
660         private readonly DbExpressionBinding _input;
661         private readonly System.Collections.ObjectModel.ReadOnlyCollection<DbSortClause> _keys;
662
663         internal DbSortExpression(TypeUsage resultType, DbExpressionBinding input, System.Collections.ObjectModel.ReadOnlyCollection<DbSortClause> sortOrder)
664             : base(DbExpressionKind.Sort, resultType)
665         {
666             Debug.Assert(input != null, "DbSortExpression input cannot be null");
667             Debug.Assert(sortOrder != null, "DbSortExpression sort order cannot be null");
668             Debug.Assert(TypeSemantics.IsCollectionType(resultType), "DbSkipExpression requires a collection result type");
669
670             this._input = input;
671             this._keys = sortOrder;
672         }
673
674         /// <summary>
675         /// Gets the <see cref="DbExpressionBinding"/> that specifies the input set.
676         /// </summary>
677         public DbExpressionBinding Input { get { return _input; } }
678
679         /// <summary>
680         /// Gets a <see cref="DbSortClause"/> list that defines the sort order.
681         /// </summary>
682         public IList<DbSortClause> SortOrder { get { return _keys; } }
683
684         /// <summary>
685         /// The visitor pattern method for expression visitors that do not produce a result value.
686         /// </summary>
687         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
688         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
689         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
690
691         /// <summary>
692         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
693         /// </summary>
694         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
695         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
696         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
697         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
698         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
699     }
700              
701     /// <summary>
702     /// Represents the set union (without duplicate removal) operation between the left and right operands.
703     /// </summary>
704     /// <remarks>
705     /// DbUnionAllExpression requires that its arguments have a common collection result type
706     /// </remarks>
707     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
708     public sealed class DbUnionAllExpression : DbBinaryExpression
709     {
710         internal DbUnionAllExpression(TypeUsage resultType, DbExpression left, DbExpression right)
711             : base(DbExpressionKind.UnionAll, resultType, left, right)
712         {
713         }
714
715         /// <summary>
716         /// The visitor pattern method for expression visitors that do not produce a result value.
717         /// </summary>
718         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
719         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
720         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
721
722         /// <summary>
723         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
724         /// </summary>
725         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
726         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
727         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
728         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
729         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
730     }     
731 }