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 { DbAndExpression(TypeUsage booleanResultType, DbExpression left, DbExpression right)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> Accept(DbExpressionVisitor visitor)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> Accept(DbExpressionVisitor<TResultType> visitor)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 { DbOrExpression(TypeUsage booleanResultType, DbExpression left, DbExpression right)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> Accept(DbExpressionVisitor visitor)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> Accept(DbExpressionVisitor<TResultType> visitor)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 { DbNotExpression(TypeUsage booleanResultType, DbExpression argument)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> Accept(DbExpressionVisitor visitor)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> Accept(DbExpressionVisitor<TResultType> visitor)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 DbArithmeticExpression(DbExpressionKind kind, TypeUsage numericResultType, DbExpressionList args)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> Accept(DbExpressionVisitor visitor)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> Accept(DbExpressionVisitor<TResultType> visitor)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 DbCaseExpression(TypeUsage commonResultType, DbExpressionList whens, DbExpressionList thens, DbExpression elseExpr)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> Accept(DbExpressionVisitor visitor)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> Accept(DbExpressionVisitor<TResultType> visitor)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 { DbCastExpression(TypeUsage type, DbExpression argument)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> Accept(DbExpressionVisitor visitor)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> Accept(DbExpressionVisitor<TResultType> visitor)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 { DbComparisonExpression(DbExpressionKind kind, TypeUsage booleanResultType, DbExpression left, DbExpression right)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> Accept(DbExpressionVisitor visitor)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> Accept(DbExpressionVisitor<TResultType> visitor)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 { DbIsEmptyExpression(TypeUsage booleanResultType, DbExpression argument)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> Accept(DbExpressionVisitor visitor)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> Accept(DbExpressionVisitor<TResultType> visitor)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 { DbIsNullExpression(TypeUsage booleanResultType, DbExpression arg, bool isRowTypeArgumentAllowed)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> Accept(DbExpressionVisitor visitor)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> Accept(DbExpressionVisitor<TResultType> visitor)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 DbIsOfExpression(DbExpressionKind isOfKind, TypeUsage booleanResultType, DbExpression argument, TypeUsage isOfType)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> Accept(DbExpressionVisitor visitor)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> Accept(DbExpressionVisitor<TResultType> visitor)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 DbOfTypeExpression(DbExpressionKind ofTypeKind, TypeUsage collectionResultType, DbExpression argument, TypeUsage type)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> Accept(DbExpressionVisitor visitor)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> Accept(DbExpressionVisitor<TResultType> visitor)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 { DbTreatExpression(TypeUsage asType, DbExpression argument)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> Accept(DbExpressionVisitor visitor)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> Accept(DbExpressionVisitor<TResultType> visitor)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 DbLikeExpression(TypeUsage booleanResultType, DbExpression input, DbExpression pattern, DbExpression escape)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> Accept(DbExpressionVisitor visitor)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> Accept(DbExpressionVisitor<TResultType> visitor)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 { DbEntityRefExpression(TypeUsage refResultType, DbExpression entity)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> Accept(DbExpressionVisitor visitor)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> Accept(DbExpressionVisitor<TResultType> visitor)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 { DbRefKeyExpression(TypeUsage rowResultType, DbExpression reference)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> Accept(DbExpressionVisitor visitor)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> Accept(DbExpressionVisitor<TResultType> visitor)593 public override TResultType Accept<TResultType>(DbExpressionVisitor<TResultType> visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } 594 } 595 } 596