45e384904198fb32eae72b251259c8008506cf1e
[mono.git] / mcs / class / referencesource / System.Data.Entity / System / Data / Common / CommandTrees / OperatorExpressions.cs
1 //---------------------------------------------------------------------
2 // <copyright file="OperatorExpressions.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.Diagnostics;
13 using System.Globalization;
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     #region Boolean Operators
22     /// <summary>
23     /// Represents the logical And of two Boolean arguments.
24     /// </summary>
25     /// <remarks>DbAndExpression requires that both of its arguments have a Boolean result type</remarks>
26     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
27     public sealed class DbAndExpression : DbBinaryExpression
28     {
29         internal DbAndExpression(TypeUsage booleanResultType, DbExpression left, DbExpression right)
30             : base(DbExpressionKind.And, booleanResultType, left, right)
31         {
32             Debug.Assert(TypeSemantics.IsPrimitiveType(booleanResultType, PrimitiveTypeKind.Boolean), "DbAndExpression requires a Boolean result type");
33         }
34
35         /// <summary>
36         /// The visitor pattern method for expression visitors that do not produce a result value.
37         /// </summary>
38         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
39         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
40         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
41
42         /// <summary>
43         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
44         /// </summary>
45         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
46         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
47         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
48         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
49         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
50     }
51
52     /// <summary>
53     /// Represents the logical Or of two Boolean arguments.
54     /// </summary>
55     /// <remarks>DbOrExpression requires that both of its arguments have a Boolean result type</remarks>
56     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
57     public sealed class DbOrExpression : DbBinaryExpression
58     {
59         internal DbOrExpression(TypeUsage booleanResultType, DbExpression left, DbExpression right)
60             : base(DbExpressionKind.Or, booleanResultType, left, right)
61         {
62             Debug.Assert(TypeSemantics.IsPrimitiveType(booleanResultType, PrimitiveTypeKind.Boolean), "DbOrExpression requires a Boolean result type");
63         }
64
65         /// <summary>
66         /// The visitor pattern method for expression visitors that do not produce a result value.
67         /// </summary>
68         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
69         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
70         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
71
72         /// <summary>
73         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
74         /// </summary>
75         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
76         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
77         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
78         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
79         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
80     }
81
82     /// <summary>
83     /// Represents the logical Not of a single Boolean argument.
84     /// </summary>
85     /// <remarks>DbNotExpression requires that its argument has a Boolean result type</remarks>
86     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
87     public sealed class DbNotExpression : DbUnaryExpression
88     {
89         internal DbNotExpression(TypeUsage booleanResultType, DbExpression argument)
90             : base(DbExpressionKind.Not, booleanResultType, argument)
91         {
92             Debug.Assert(TypeSemantics.IsPrimitiveType(booleanResultType, PrimitiveTypeKind.Boolean), "DbNotExpression requires a Boolean result type");
93         }
94
95         /// <summary>
96         /// The visitor pattern method for expression visitors that do not produce a result value.
97         /// </summary>
98         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
99         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
100         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
101
102         /// <summary>
103         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
104         /// </summary>
105         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
106         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
107         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
108         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
109         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
110     }
111     #endregion
112
113     /// <summary>
114     /// Represents an arithmetic operation (addition, subtraction, multiplication, division, modulo or negation) applied to two numeric arguments.
115     /// </summary>
116     /// <remarks>DbArithmeticExpression requires that its arguments have a common numeric result type</remarks>
117     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
118     public sealed class DbArithmeticExpression : DbExpression
119     {
120         private readonly DbExpressionList _args;
121
122         internal DbArithmeticExpression(DbExpressionKind kind, TypeUsage numericResultType, DbExpressionList args)
123             : base(kind, numericResultType)
124         {
125             Debug.Assert(TypeSemantics.IsNumericType(numericResultType), "DbArithmeticExpression result type must be numeric");
126             
127             Debug.Assert(
128                 DbExpressionKind.Divide == kind ||
129                 DbExpressionKind.Minus == kind ||
130                 DbExpressionKind.Modulo == kind ||
131                 DbExpressionKind.Multiply == kind ||
132                 DbExpressionKind.Plus == kind ||
133                 DbExpressionKind.UnaryMinus == kind,
134                 "Invalid DbExpressionKind used in DbArithmeticExpression: " + Enum.GetName(typeof(DbExpressionKind), kind)
135             );
136
137             Debug.Assert(args != null, "DbArithmeticExpression arguments cannot be null");
138
139             Debug.Assert(
140                 (DbExpressionKind.UnaryMinus == kind && 1 == args.Count) ||
141                 2 == args.Count,
142                 "Incorrect number of arguments specified to DbArithmeticExpression"
143             );
144
145             this._args = args;            
146         }
147
148         /// <summary>
149         /// Gets the list of expressions that define the current arguments.
150         /// </summary>
151         /// <remarks>
152         ///     The <code>Arguments</code> property returns a fixed-size list of <see cref="DbExpression"/> elements.
153         ///     <see cref="DbArithmeticExpression"/> requires that all elements of it's <code>Arguments</code> list
154         ///     have a common numeric result type.
155         /// </remarks>
156         public IList<DbExpression> Arguments { get { return _args; } }
157
158         /// <summary>
159         /// The visitor pattern method for expression visitors that do not produce a result value.
160         /// </summary>
161         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
162         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
163         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
164
165         /// <summary>
166         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
167         /// </summary>
168         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
169         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
170         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
171         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
172         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
173     }
174
175     /// <summary>
176     /// Represents a Case When...Then...Else logical operation.
177     /// </summary>
178     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
179     public sealed class DbCaseExpression : DbExpression
180     {
181         private readonly DbExpressionList _when;
182         private readonly DbExpressionList _then;
183         private readonly DbExpression _else;
184
185         internal DbCaseExpression(TypeUsage commonResultType, DbExpressionList whens, DbExpressionList thens, DbExpression elseExpr)
186             : base(DbExpressionKind.Case, commonResultType)
187         {
188             Debug.Assert(whens != null, "DbCaseExpression whens cannot be null");
189             Debug.Assert(thens != null, "DbCaseExpression thens cannot be null");
190             Debug.Assert(elseExpr != null, "DbCaseExpression else cannot be null");
191             Debug.Assert(whens.Count == thens.Count, "DbCaseExpression whens count must match thens count");
192
193             this._when = whens;
194             this._then = thens;
195             this._else = elseExpr;
196         }
197
198         /// <summary>
199         /// Gets the When clauses of this DbCaseExpression.
200         /// </summary>
201         public IList<DbExpression> When { get { return _when; } }
202
203         /// <summary>
204         /// Gets the Then clauses of this DbCaseExpression.
205         /// </summary>
206         public IList<DbExpression> Then { get { return _then; } }
207
208         /// <summary>
209         /// Gets the Else clause of this DbCaseExpression.
210         /// </summary>
211         public DbExpression Else { get { return _else; } }
212
213         /// <summary>
214         /// The visitor pattern method for expression visitors that do not produce a result value.
215         /// </summary>
216         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
217         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
218         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
219
220         /// <summary>
221         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
222         /// </summary>
223         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
224         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
225         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
226         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
227         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
228     }
229
230     /// <summary>
231     /// Represents a cast operation applied to a polymorphic argument.
232     /// </summary>
233     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
234     public sealed class DbCastExpression : DbUnaryExpression
235     {
236         internal DbCastExpression(TypeUsage type, DbExpression argument)
237             : base(DbExpressionKind.Cast, type, argument)
238         {
239             Debug.Assert(TypeSemantics.IsCastAllowed(argument.ResultType, type), "DbCastExpression represents an invalid cast");
240         }
241
242         /// <summary>
243         /// The visitor pattern method for expression visitors that do not produce a result value.
244         /// </summary>
245         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
246         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
247         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
248
249         /// <summary>
250         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
251         /// </summary>
252         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
253         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
254         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
255         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
256         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
257     }
258
259     /// <summary>
260     /// Represents a comparison operation (equality, greater than, greather than or equal, less than, less than or equal, inequality) applied to two arguments.
261     /// </summary>
262     /// <remarks>
263     ///     DbComparisonExpression requires that its arguments have a common result type
264     ///     that is equality comparable (for <see cref="DbExpressionKind"/>.Equals and <see cref="DbExpressionKind"/>.NotEquals),
265     ///     order comparable (for <see cref="DbExpressionKind"/>.GreaterThan and <see cref="DbExpressionKind"/>.LessThan),
266     ///     or both (for <see cref="DbExpressionKind"/>.GreaterThanOrEquals and <see cref="DbExpressionKind"/>.LessThanOrEquals).
267     /// </remarks>
268     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
269     public sealed class DbComparisonExpression : DbBinaryExpression
270     {
271         internal DbComparisonExpression(DbExpressionKind kind, TypeUsage booleanResultType, DbExpression left, DbExpression right)
272             : base(kind, booleanResultType, left, right)
273         {
274             Debug.Assert(left != null, "DbComparisonExpression left cannot be null");
275             Debug.Assert(right != null, "DbComparisonExpression right cannot be null");
276             Debug.Assert(TypeSemantics.IsBooleanType(booleanResultType), "DbComparisonExpression result type must be a Boolean type");
277             Debug.Assert(
278                 DbExpressionKind.Equals == kind ||
279                 DbExpressionKind.LessThan == kind ||
280                 DbExpressionKind.LessThanOrEquals == kind ||
281                 DbExpressionKind.GreaterThan == kind ||
282                 DbExpressionKind.GreaterThanOrEquals == kind ||
283                 DbExpressionKind.NotEquals == kind,
284                 "Invalid DbExpressionKind used in DbComparisonExpression: " + Enum.GetName(typeof(DbExpressionKind), kind)
285             );
286         }
287         
288         /// <summary>
289         /// The visitor pattern method for expression visitors that do not produce a result value.
290         /// </summary>
291         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
292         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
293         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
294
295         /// <summary>
296         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
297         /// </summary>
298         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
299         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
300         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
301         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
302         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }                
303     }
304
305     /// <summary>
306     /// Represents empty set determination applied to a single set argument.
307     /// </summary>
308     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
309     public sealed class DbIsEmptyExpression : DbUnaryExpression
310     {
311         internal DbIsEmptyExpression(TypeUsage booleanResultType, DbExpression argument)
312             : base(DbExpressionKind.IsEmpty, booleanResultType, argument)
313         {
314             Debug.Assert(TypeSemantics.IsBooleanType(booleanResultType), "DbIsEmptyExpression requires a Boolean result type");
315         }
316
317         /// <summary>
318         /// The visitor pattern method for expression visitors that do not produce a result value.
319         /// </summary>
320         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
321         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
322         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
323
324         /// <summary>
325         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
326         /// </summary>
327         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
328         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
329         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
330         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
331         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
332     }
333
334     /// <summary>
335     /// Represents null determination applied to a single argument.
336     /// </summary>
337     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
338     public sealed class DbIsNullExpression : DbUnaryExpression
339     {
340         internal DbIsNullExpression(TypeUsage booleanResultType, DbExpression arg, bool isRowTypeArgumentAllowed)
341             : base(DbExpressionKind.IsNull, booleanResultType, arg)
342         {
343             Debug.Assert(TypeSemantics.IsBooleanType(booleanResultType), "DbIsNullExpression requires a Boolean result type");
344         }
345
346         /// <summary>
347         /// The visitor pattern method for expression visitors that do not produce a result value.
348         /// </summary>
349         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
350         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
351         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
352
353         /// <summary>
354         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
355         /// </summary>
356         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
357         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
358         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
359         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
360         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
361     }
362
363     /// <summary>
364     /// Represents the type comparison of a single argument against the specified type.
365     /// </summary>
366     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
367     public sealed class DbIsOfExpression : DbUnaryExpression
368     {
369         private TypeUsage _ofType;
370
371         internal DbIsOfExpression(DbExpressionKind isOfKind, TypeUsage booleanResultType, DbExpression argument, TypeUsage isOfType)
372             : base(isOfKind, booleanResultType, argument)
373         {
374             Debug.Assert(DbExpressionKind.IsOf == this.ExpressionKind || DbExpressionKind.IsOfOnly == this.ExpressionKind, string.Format(CultureInfo.InvariantCulture, "Invalid DbExpressionKind used in DbIsOfExpression: {0}", Enum.GetName(typeof(DbExpressionKind), this.ExpressionKind)));
375             Debug.Assert(TypeSemantics.IsBooleanType(booleanResultType), "DbIsOfExpression requires a Boolean result type");
376
377             this._ofType = isOfType;
378         }
379
380         /// <summary>
381         /// Gets the type metadata that the type metadata of the argument should be compared to.
382         /// </summary>
383         public TypeUsage OfType
384         {
385             get { return _ofType; }
386         }
387
388         /// <summary>
389         /// The visitor pattern method for expression visitors that do not produce a result value.
390         /// </summary>
391         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
392         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
393         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
394
395         /// <summary>
396         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
397         /// </summary>
398         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
399         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
400         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
401         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
402         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
403     }
404
405     /// <summary>
406     /// Represents the retrieval of elements of the specified type from the given set argument.
407     /// </summary>
408     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
409     public sealed class DbOfTypeExpression : DbUnaryExpression
410     {
411         private readonly TypeUsage _ofType;
412
413         internal DbOfTypeExpression(DbExpressionKind ofTypeKind, TypeUsage collectionResultType, DbExpression argument, TypeUsage type)
414             : base(ofTypeKind, collectionResultType, argument)
415         {
416             Debug.Assert(DbExpressionKind.OfType == ofTypeKind ||
417                          DbExpressionKind.OfTypeOnly == ofTypeKind,
418                          "ExpressionKind for DbOfTypeExpression must be OfType or OfTypeOnly");
419
420             //
421             // Assign the requested element type to the OfType property.
422             //
423             this._ofType = type;
424         }
425
426         /// <summary>
427         /// Gets the metadata of the type of elements that should be retrieved from the set argument.
428         /// </summary>
429         public TypeUsage OfType
430         {
431             get { return _ofType; }
432         }
433
434         /// <summary>
435         /// The visitor pattern method for expression visitors that do not produce a result value.
436         /// </summary>
437         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
438         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
439         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
440
441         /// <summary>
442         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
443         /// </summary>
444         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
445         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
446         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
447         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
448         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
449     }
450
451     /// <summary>
452     /// Represents the type conversion of a single argument to the specified type.
453     /// </summary>
454     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
455     public sealed class DbTreatExpression : DbUnaryExpression
456     {
457         internal DbTreatExpression(TypeUsage asType, DbExpression argument)
458             : base(DbExpressionKind.Treat, asType, argument)
459         {
460             Debug.Assert(TypeSemantics.IsValidPolymorphicCast(argument.ResultType, asType), "DbTreatExpression represents an invalid treat");
461         }
462
463         /// <summary>
464         /// The visitor pattern method for expression visitors that do not produce a result value.
465         /// </summary>
466         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
467         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
468         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
469
470         /// <summary>
471         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
472         /// </summary>
473         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
474         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
475         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
476         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
477         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
478     }
479
480     /// <summary>
481     /// Represents a string comparison against the specified pattern with an optional escape string
482     /// </summary>
483     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
484     public sealed class DbLikeExpression : DbExpression
485     {
486         private readonly DbExpression _argument;
487         private readonly DbExpression _pattern;
488         private readonly DbExpression _escape;
489
490         internal DbLikeExpression(TypeUsage booleanResultType, DbExpression input, DbExpression pattern, DbExpression escape)
491             : base(DbExpressionKind.Like, booleanResultType)
492         {
493             Debug.Assert(input != null, "DbLikeExpression argument cannot be null");
494             Debug.Assert(pattern != null, "DbLikeExpression pattern cannot be null");
495             Debug.Assert(escape != null, "DbLikeExpression escape cannot be null");
496             Debug.Assert(TypeSemantics.IsPrimitiveType(input.ResultType, PrimitiveTypeKind.String), "DbLikeExpression argument must have a string result type");
497             Debug.Assert(TypeSemantics.IsPrimitiveType(pattern.ResultType, PrimitiveTypeKind.String), "DbLikeExpression pattern must have a string result type");
498             Debug.Assert(TypeSemantics.IsPrimitiveType(escape.ResultType, PrimitiveTypeKind.String), "DbLikeExpression escape must have a string result type");
499             Debug.Assert(TypeSemantics.IsBooleanType(booleanResultType), "DbLikeExpression must have a Boolean result type");
500
501             this._argument = input;
502             this._pattern = pattern;
503             this._escape = escape;
504         }
505
506         /// <summary>
507         /// Gets the expression that specifies the string to compare against the given pattern
508         /// </summary>
509         public DbExpression Argument { get { return _argument; } }
510
511         /// <summary>
512         /// Gets the expression that specifies the pattern against which the given string should be compared
513         /// </summary>
514         public DbExpression Pattern { get { return _pattern; } }
515
516         /// <summary>
517         /// Gets the expression that provides an optional escape string to use for the comparison
518         /// </summary>
519         public DbExpression Escape { get { return _escape; } }
520
521         /// <summary>
522         /// The visitor pattern method for expression visitors that do not produce a result value.
523         /// </summary>
524         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
525         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
526         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
527
528         /// <summary>
529         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
530         /// </summary>
531         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
532         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
533         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
534         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
535         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
536     }
537
538     /// <summary>
539     /// Represents the retrieval of a reference to the specified Entity as a Ref.
540     /// </summary>
541     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
542     public sealed class DbEntityRefExpression : DbUnaryExpression
543     {
544         internal DbEntityRefExpression(TypeUsage refResultType, DbExpression entity)
545             : base(DbExpressionKind.EntityRef, refResultType, entity)
546         {
547             Debug.Assert(TypeSemantics.IsReferenceType(refResultType), "DbEntityRefExpression requires a reference result type");
548         }
549
550         /// <summary>
551         /// The visitor pattern method for expression visitors that do not produce a result value.
552         /// </summary>
553         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
554         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
555         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
556
557         /// <summary>
558         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
559         /// </summary>
560         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
561         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
562         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
563         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
564         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
565     }
566
567     /// <summary>
568     /// Represents the retrieval of the key value of the specified Reference as a row.
569     /// </summary>
570     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
571     public sealed class DbRefKeyExpression : DbUnaryExpression
572     {
573         internal DbRefKeyExpression(TypeUsage rowResultType, DbExpression reference)
574             : base(DbExpressionKind.RefKey, rowResultType, reference)
575         {
576             Debug.Assert(TypeSemantics.IsRowType(rowResultType), "DbRefKeyExpression requires a row result type");
577         }
578
579         /// <summary>
580         /// The visitor pattern method for expression visitors that do not produce a result value.
581         /// </summary>
582         /// <param name="visitor">An instance of DbExpressionVisitor.</param>
583         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
584         public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
585
586         /// <summary>
587         /// The visitor pattern method for expression visitors that produce a result value of a specific type.
588         /// </summary>
589         /// <param name="visitor">An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.</param>
590         /// <typeparam name="TResultType">The type of the result produced by <paramref name="visitor"/></typeparam>
591         /// <exception cref="ArgumentNullException"><paramref name="visitor"/> is null</exception>
592         /// <returns>An instance of <typeparamref name="TResultType"/>.</returns>
593         public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
594     }
595 }