Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DataEntity / System / Data / Common / CommandTrees / ValueExpressions.cs / 2 / ValueExpressions.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....], [....] //--------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Data.Common; using System.Data.Metadata.Edm; using System.Data.Common.CommandTrees.Internal; namespace System.Data.Common.CommandTrees { ////// Represents a constant value. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] public sealed class DbConstantExpression : DbExpression { private object _value; internal DbConstantExpression(DbCommandTree commandTree, object value) : base(commandTree, DbExpressionKind.Constant) { if (null == value) { throw EntityUtil.ArgumentNull("value"); } // // Check that typeof(value) is actually a valid constant (i.e. primitive) type // PrimitiveTypeKind primitiveTypeKind; if (!CommandTreeUtils.TryGetPrimtiveTypeKind(value.GetType(), out primitiveTypeKind)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Constant_InvalidType, "value"); } TypeUsage typeMeta = TypeHelpers.GetLiteralTypeUsage(primitiveTypeKind); // // Set the value // _value = value; this.ResultType = typeMeta; } internal DbConstantExpression(DbCommandTree commandTree, object value, TypeUsage constantType) : base(commandTree, DbExpressionKind.Constant) { // // Basic validation of constant value and constant type (non-null, read-only, etc) // EntityUtil.CheckArgumentNull(value, "value"); commandTree.TypeHelper.CheckType(constantType, "constantType"); // // Verify that constantType is a primitive type and that value is an instance of that primitive type // Note that the value is not validated against applicable facets (such as MaxLength for a string value), // this is left to the server. // PrimitiveType primitiveType; if (!TypeHelpers.TryGetEdmType(constantType, out primitiveType)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Constant_InvalidConstantType(constantType.ToString()), "constantType"); } PrimitiveTypeKind valueKind; if (!CommandTreeUtils.TryGetPrimtiveTypeKind(value.GetType(), out valueKind) || primitiveType.PrimitiveTypeKind != valueKind) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Constant_InvalidValueForType(constantType.ToString()), "value"); } // // Set the value // _value = value; this.ResultType = constantType; } /// /// Gets the constant value. /// public object Value { get { return _value; } } ////// The visitor pattern method for expression visitors that do not produce a result value. /// /// An instance of DbExpressionVisitor. ///public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } /// is null /// The visitor pattern method for expression visitors that produce a result value of a specific type. /// /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. ///The type of the result produced by ////// is null An instance of public override TResultType Accept. (DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } } /// /// Represents null. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] public sealed class DbNullExpression : DbExpression { internal DbNullExpression(DbCommandTree commandTree, TypeUsage type) : base(commandTree, DbExpressionKind.Null) { commandTree.TypeHelper.CheckType(type); this.ResultType = type; } ////// The visitor pattern method for expression visitors that do not produce a result value. /// /// An instance of DbExpressionVisitor. ///public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } /// is null /// The visitor pattern method for expression visitors that produce a result value of a specific type. /// /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. ///The type of the result produced by ////// is null An instance of public override TResultType Accept. (DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } } /// /// Represents a reference to a variable that is currently in scope. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] public sealed class DbVariableReferenceExpression : DbExpression { private string _name; internal DbVariableReferenceExpression(DbCommandTree cmdTree, TypeUsage type, string name) : base(cmdTree, DbExpressionKind.VariableReference) { if (string.IsNullOrEmpty(name)) { throw EntityUtil.ArgumentNull("name"); } // // Verify the type of the reference. NullType is not allowed in Var or Parameter references. // cmdTree.TypeHelper.CheckType(type); _name = name; this.ResultType = type; } ////// Gets the name of the referenced variable. /// public string VariableName { get { return _name; } } ////// The visitor pattern method for expression visitors that do not produce a result value. /// /// An instance of DbExpressionVisitor. ///public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } /// is null /// The visitor pattern method for expression visitors that produce a result value of a specific type. /// /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. ///The type of the result produced by ////// is null An instance of public override TResultType Accept. (DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } } /// /// Represents a reference to a parameter declared on the command tree that contains this expression. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] public sealed class DbParameterReferenceExpression : DbExpression { private string _name; internal DbParameterReferenceExpression(DbCommandTree cmdTree, TypeUsage type, string name) : base(cmdTree, DbExpressionKind.ParameterReference) { EntityUtil.CheckArgumentNull(name, "name"); // DbCommandTree.CreateParameterRefExpression should check that a parameter with the given name exists, // and DbCommandTree.AddParameter should have already verified that the name is valid, so this need only // be asserted here. Debug.Assert(DbCommandTree.IsValidParameterName(name), string.Format(CultureInfo.InvariantCulture, "Invalid parameter name passed to DbParameterReferenceExpression constructor: '{0}'", name)); // // Verify the type of the reference. NullType is not allowed in Var or Parameter references. // cmdTree.TypeHelper.CheckType(type); _name = name; this.ResultType = type; } ////// Gets the name of the referenced parameter. /// public string ParameterName { get { return _name; } } ////// The visitor pattern method for expression visitors that do not produce a result value. /// /// An instance of DbExpressionVisitor. ///public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } /// is null /// The visitor pattern method for expression visitors that produce a result value of a specific type. /// /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. ///The type of the result produced by ////// is null An instance of public override TResultType Accept. (DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } } /// /// Represents the retrieval of a static or instance property. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] public sealed class DbPropertyExpression : DbExpression { private EdmMember _property; private ExpressionLink _instance; private void InitializeFromMember(DbCommandTree tree, EdmMember member, DbExpression instance) { // // Validate the instance // if (null == instance) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Property_InstanceRequiredForInstance, "instance"); } TypeUsage instanceType = TypeUsage.Create(member.DeclaringType); _instance = new ExpressionLink("Instance", tree, instanceType, instance); Debug.Assert(!TypeSemantics.IsNullOrNullType(Helper.GetModelTypeUsage(member)), "EdmMember metadata has a TypeUsage of null or NullType"); _property = member; this.ResultType = Helper.GetModelTypeUsage(member); } internal DbPropertyExpression(DbCommandTree cmdTree, EdmProperty propertyInfo, DbExpression instance) : base(cmdTree, DbExpressionKind.Property) { // // Ensure that the property metadata is non-null and from the same metadata workspace and dataspace as the command tree. // cmdTree.TypeHelper.CheckMember(propertyInfo, "propertyInfo"); InitializeFromMember(cmdTree, propertyInfo, instance); } internal DbPropertyExpression(DbCommandTree cmdTree, RelationshipEndMember memberInfo, DbExpression instance) : base(cmdTree, DbExpressionKind.Property) { // // Ensure that the relationship end metadata is non-null and from the same metadata workspace and dataspace as the command tree. // cmdTree.TypeHelper.CheckMember(memberInfo, "memberInfo"); InitializeFromMember(cmdTree, memberInfo, instance); } internal DbPropertyExpression(DbCommandTree cmdTree, NavigationProperty propertyInfo, DbExpression instance) : base(cmdTree, DbExpressionKind.Property) { // // Ensure that the navigation property metadata is non-null and from the same metadata workspace and dataspace as the command tree. // cmdTree.TypeHelper.CheckMember(propertyInfo, "propertyInfo"); InitializeFromMember(cmdTree, propertyInfo, instance); } ////// Gets the property metadata for the property to retrieve. /// public EdmMember Property { get { return _property; } } ////// Gets or sets an ///that defines the instance from which the property should be retrieved. /// The expression is null ////// The expression is not associated with the DbPropertyExpression's command tree, /// or its result type is not equal or promotable to the type that defines the property /// public DbExpression Instance { get { return _instance.Expression; } /*CQT_PUBLIC_API(*/internal/*)*/ set { _instance.Expression = value; } } ////// The visitor pattern method for expression visitors that do not produce a result value. /// /// An instance of DbExpressionVisitor. ///public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } /// is null /// The visitor pattern method for expression visitors that produce a result value of a specific type. /// /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. ///The type of the result produced by ////// is null An instance of public override TResultType Accept. (DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } } /// /// Represents the invocation of a function. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] public sealed class DbFunctionExpression : DbExpression { private EdmFunction _functionInfo; private IList_args; private ExpressionLink _lambdaBody; internal DbFunctionExpression(DbCommandTree cmdTree, EdmFunction function, DbExpression lambdaBody, IList args) : base(cmdTree, DbExpressionKind.Function) { // // Ensure that the function metadata is non-null and from the same metadata workspace and dataspace as the command tree. // Lambda functions are not verified since all of their components (return type, parameter types) have already been // checked and because they have not been added to a metadata collection because they are not directly associated with // a particular metadata workspace. Iff a function is a Lambda function will the Lambda body argument be non-null. // if (null == lambdaBody) { cmdTree.TypeHelper.CheckFunction(function); } // // Non-composable functions or functions including command text are not permitted in expressions -- they can only be // executed independently // if (!function.IsComposableAttribute) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Function_NonComposableInExpression, "function"); } if (!String.IsNullOrEmpty(function.CommandTextAttribute)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Function_CommandTextInExpression, "function"); } // // Functions that return void are not allowed // if (null == function.ReturnParameter || TypeSemantics.IsNullOrNullType(function.ReturnParameter.TypeUsage)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Function_VoidResultInvalid, "function"); } // // Validate the arguments // EntityUtil.CheckArgumentNull(args, "args"); _args = new ExpressionList("Arguments", cmdTree, function.Parameters, args); _functionInfo = function; // // Is this a 'Lambda' function invocation? // if(lambdaBody != null) { _lambdaBody = new ExpressionLink("LambdaBody", cmdTree, lambdaBody); } this.ResultType = function.ReturnParameter.TypeUsage; } /// /// Gets the metadata for the function to invoke. /// public EdmFunction Function { get { return _functionInfo; } } ////// Gets an public IListlist that provides the arguments to the function. /// Arguments { get { return _args; } } /// /// Gets a Boolean value indicating whether or not the function to invoke is an inline function definition (Lambda function). /// /*CQT_PUBLIC_API(*/internal/*)*/ bool IsLambda { get { return _lambdaBody != null; } } ////// Gets the DbExpression that provides the Body of the referenced function if that function is a Lambda function /// /*CQT_PUBLIC_API(*/internal/*)*/ DbExpression LambdaBody { get { if (_lambdaBody != null) { return _lambdaBody.Expression; } return null; } set { if (null == _lambdaBody) { throw EntityUtil.NotSupported(System.Data.Entity.Strings.Cqt_Function_BodyOnlyValidForLambda); } _lambdaBody.Expression = value; } } ////// The visitor pattern method for expression visitors that do not produce a result value. /// /// An instance of DbExpressionVisitor. ///public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } /// is null /// The visitor pattern method for expression visitors that produce a result value of a specific type. /// /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. ///The type of the result produced by ////// is null An instance of public override TResultType Accept. (DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } #region Lambda function namespace and name internal static string LambdaFunctionNameSpace { get { return "System.Data.Common.CommandTrees.LambdaFunctions"; } } internal static string LambdaFunctionName { get { return "Lambda"; } } #endregion } #if METHOD_EXPRESSION /// /// Represents the invocation of a method. /// public sealed class MethodExpression : Expression { MethodMetadata m_methodInfo; IListm_args; ExpressionLink m_inst; internal MethodExpression(CommandTree cmdTree, MethodMetadata methodInfo, IList args, Expression instance) : base(cmdTree, ExpressionKind.Method) { // // Ensure that the property metadata is non-null and from the same metadata workspace and dataspace as the command tree. // cmdTree.TypeHelper.CheckMember(methodInfo, "method", "methodInfo"); // // Methods that return void are not allowed // if (cmdTree.TypeHelper.IsNullOrNullType(methodInfo.Type)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Method_VoidResultInvalid, "methodInfo"); } if (null == args) { throw EntityUtil.ArgumentNull("args"); } this.m_inst = new ExpressionLink("Instance", cmdTree); // // Validate the instance // if (methodInfo.IsStatic) { if (instance != null) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Method_InstanceInvalidForStatic, "instance"); } } else { if (null == instance) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Method_InstanceRequiredForInstance, "instance"); } this.m_inst.SetExpectedType(methodInfo.DefiningType); this.m_inst.InitializeValue(instance); } // // Validate the arguments // m_args = new ExpressionList("Arguments", cmdTree, methodInfo.Parameters, args); m_methodInfo = methodInfo; this.ResultType = methodInfo.Type; } /// /// Gets the metadata for the method to invoke. /// public MethodMetadata Method { get { return m_methodInfo; } } ////// Gets the expressions that provide the arguments to the method. /// public IListArguments { get { return m_args; } } /// /// Gets or sets an ///that defines the instance on which the method should be invoked. Must be null for instance methods. /// For static properties, Instance
will always be null, and attempting to set a new value will result /// in. /// The expression is null ///The method is static ////// The expression is not associated with the MethodExpression's command tree, /// or its result type is not equal or promotable to the type that defines the method /// public Expression Instance { get { return m_inst.Expression; } /*CQT_PUBLIC_API(*/internal/*)*/ set { if (this.m_methodInfo.IsStatic) { throw EntityUtil.NotSupported(System.Data.Entity.Strings.Cqt_Method_InstanceInvalidForStatic); } this.m_inst.Expression = value; } } ////// The visitor pattern method for expression visitors that do not produce a result value. /// /// An instance of ExpressionVisitor. ///public override void Accept(ExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } /// is null /// The visitor pattern method for expression visitors that produce a result value of a specific type. /// /// An instance of a typed ExpressionVisitor that produces a result value of type TResultType. ///The type of the result produced by ////// is null An instance of public override TResultType Accept. (DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } } #endif /// /// Represents the navigation of a (composition or association) relationship given the 'from' role, the 'to' role and an instance of the from role /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] public sealed class DbRelationshipNavigationExpression : DbExpression { private RelationshipType _relation; private RelationshipEndMember _fromRole; private RelationshipEndMember _toRole; private ExpressionLink _from; internal DbRelationshipNavigationExpression( DbCommandTree cmdTree, RelationshipEndMember fromEnd, RelationshipEndMember toEnd, DbExpression from) : base(cmdTree, DbExpressionKind.RelationshipNavigation) { // // Validate the relationship ends before use // this.CheckEnds(fromEnd, toEnd); RelationshipType relType = fromEnd.DeclaringType as RelationshipType; // // Ensure that the relation type is non-null and from the same metadata workspace as the command tree // CommandTreeTypeHelper.CheckType(relType); // // Validate that the 'to' relationship end is defined by the same relationship type as the 'from' end // if (!relType.Equals(toEnd.DeclaringType)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Factory_IncompatibleRelationEnds, "toEnd"); } // // Validation was successful so initialize members and verify the source expression against the expected type // _relation = relType; _fromRole = fromEnd; _toRole = toEnd; _from = new ExpressionLink("NavigationSource", cmdTree, GetExpectedInstanceType(fromEnd, from), from); this.ResultType = GetResultType(toEnd); } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal DbRelationshipNavigationExpression( DbCommandTree cmdTree, RelationshipType type, string fromEndName, string toEndName, DbExpression from) : base(cmdTree, DbExpressionKind.RelationshipNavigation) { // // Verify that the from and to relation end names are not null // EntityUtil.CheckArgumentNull(fromEndName, "fromEndName"); EntityUtil.CheckArgumentNull(toEndName, "toEndName"); // // Ensure that the relation type is non-null and from the same metadata workspace as the command tree // CommandTreeTypeHelper.CheckType(type); // // Retrieve the relation end properties with the specified 'from' and 'to' names // RelationshipEndMember fromEnd = DbRelationshipNavigationExpression.FindEnd(type.Members, fromEndName, "fromEndName"); RelationshipEndMember toEnd = DbRelationshipNavigationExpression.FindEnd(type.Members, toEndName, "toEndName"); // // Validate the retrieved relation end properties // this.CheckEnds(fromEnd, toEnd); // // Validation was successful so initialize members and verify the source expression against the expected type // _relation = type; _fromRole = fromEnd; _toRole = toEnd; _from = new ExpressionLink("NavigationSource", cmdTree, GetExpectedInstanceType(fromEnd, from), from); this.ResultType = GetResultType(toEnd); } ////// Gets the metadata for the relationship over which navigation occurs /// public RelationshipType Relationship { get { return _relation; } } ////// Gets the metadata for the relationship end to navigate from /// public RelationshipEndMember NavigateFrom { get { return _fromRole; } } ////// Gets the metadata for the relationship end to navigate to /// public RelationshipEndMember NavigateTo { get { return _toRole; } } ////// Gets or sets an ///that specifies the instance of the 'from' relationship end from which navigation should occur. /// The expression is null ////// The expression is not associated with the DbRelationshipNavigationExpression's command tree, /// or its result type is not equal or promotable to the reference type of the NavigateFrom property. /// ///public DbExpression NavigationSource { get { return _from.Expression; } /*CQT_PUBLIC_API(*/internal/*)*/ set { _from.Expression = value; } } /// /// The visitor pattern method for expression visitors that do not produce a result value. /// /// An instance of DbExpressionVisitor. ///public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } /// is null /// The visitor pattern method for expression visitors that produce a result value of a specific type. /// /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. ///The type of the result produced by ////// is null An instance of public override TResultType Accept. (DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } /// /// Retrieves a relation end property from a given enumerable collection of members, given the name of the end. /// /// The enumerable collection of members /// The name of the end to retrieve /// The variable name to specify if an exception must be thrown ///An RelationEndProperty instance that represents the relation end with the specified name ///If no relation end with the specified name exists [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal static RelationshipEndMember FindEnd(IEnumerablemembers, string endName, string varName) { foreach (EdmMember member in members) { RelationshipEndMember end = member as RelationshipEndMember; if (end != null && end.Name.Equals(endName, StringComparison.Ordinal)) { return end; } } throw EntityUtil.ArgumentOutOfRange(System.Data.Entity.Strings.Cqt_Factory_NoSuchRelationEnd, varName); } private static TypeUsage GetExpectedInstanceType(RelationshipEndMember end, DbExpression from) { TypeUsage endType = end.TypeUsage; if (!TypeSemantics.IsReferenceType(endType)) { // // The only relation end that is currently allowed to have a non-Reference type is the Child end of // a composition, in which case the end type must be an entity type. // // Debug.Assert(end.Relation.IsComposition && !end.IsParent && (end.Type is EntityType), "Relation end can only have non-Reference type if it is a Composition child end"); endType = TypeHelpers.CreateReferenceTypeUsage(TypeHelpers.GetEdmType (endType)); } TypeUsage retType = TypeHelpers.GetCommonTypeUsage(endType, from.ResultType); if (null == retType) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelNav_WrongSourceType(TypeHelpers.GetFullName(endType)), "from"); } return retType; } private static TypeUsage GetResultType(RelationshipEndMember end) { TypeUsage retType = end.TypeUsage; if (!TypeSemantics.IsReferenceType(retType)) { // // The only relation end that is currently allowed to have a non-Reference type is the Child end of // a composition, in which case the end type must be an entity type. // //Debug.Assert(end.Relation.IsComposition && !end.IsParent && (end.Type is EntityType), "Relation end can only have non-Reference type if it is a Composition child end"); retType = TypeHelpers.CreateReferenceTypeUsage(TypeHelpers.GetEdmType (retType)); } // // If the upper bound is not 1 the result type is a collection of the given type // if (RelationshipMultiplicity.Many == end.RelationshipMultiplicity) { retType = TypeHelpers.CreateCollectionTypeUsage(retType); } return retType; } private void CheckEnds(RelationshipEndMember fromEnd, RelationshipEndMember toEnd) { // // Ensure that the 'from' role metadata is non-null and from the same metadata workspace as the command tree // this.CommandTree.TypeHelper.CheckMember(fromEnd, "fromEnd"); // // Ensure that the 'to' role metadata is non-null and from the same metadata workspace as the command tree // this.CommandTree.TypeHelper.CheckMember(toEnd, "toEnd"); } } /// /// Encapsulates the result (represented as a Ref to the resulting Entity) of navigating from /// the specified source end of a relationship to the specified target end. This class is intended /// for use only with [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] internal sealed class DbRelatedEntityRef { private readonly RelationshipEndMember _sourceEnd; private readonly RelationshipEndMember _targetEnd; private ExpressionLink _targetEntityRef; //private DbExpression _targetEntityRef; internal DbRelatedEntityRef(DbCommandTree commandTree, RelationshipEndMember sourceEnd, RelationshipEndMember targetEnd, DbExpression targetEntityRef) { // Validate that the specified relationship ends are: // 1. Non-null // 2. From the same metadata workspace as that used by the command tree commandTree.TypeHelper.CheckMember(sourceEnd, "sourceEnd"); commandTree.TypeHelper.CheckMember(targetEnd, "targetEnd"); // Validate that the specified target entity ref is: // 1. Non-null // 2. Associated with this command tree _targetEntityRef = new ExpressionLink("TargetEntityReference", commandTree); _targetEntityRef.InitializeValue(targetEntityRef); // Validate that the specified source and target ends are: // 1. Declared by the same relationship type if (!object.ReferenceEquals(sourceEnd.DeclaringType, targetEnd.DeclaringType)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelatedEntityRef_TargetEndFromDifferentRelationship, "targetEnd"); } // 2. Not the same end if (object.ReferenceEquals(sourceEnd, targetEnd)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelatedEntityRef_TargetEndSameAsSourceEnd, "targetEnd"); } // Validate that the specified target end has multiplicity of at most one if (targetEnd.RelationshipMultiplicity != RelationshipMultiplicity.One && targetEnd.RelationshipMultiplicity != RelationshipMultiplicity.ZeroOrOne) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelatedEntityRef_TargetEndMustBeAtMostOne, "targetEnd"); } // Validate that the specified target entity ref actually has a ref result type if (!TypeSemantics.IsReferenceType(targetEntityRef.ResultType)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelatedEntityRef_TargetEntityNotRef, "targetEntityRef"); } // Validate that the specified target entity is of a type that can be reached by navigating to the specified relationship end EntityTypeBase endType = TypeHelpers.GetEdmType, where an 'owning' instance of that class /// represents the source Entity involved in the relationship navigation. /// Instances of DbRelatedEntityRef may be specified when creating a that /// constructs an Entity, allowing information about Entities that are related to the newly constructed Entity to be captured. /// (targetEnd.TypeUsage).ElementType; EntityTypeBase targetType = TypeHelpers.GetEdmType (targetEntityRef.ResultType).ElementType; if (!endType.EdmEquals(targetType) && !TypeSemantics.IsSubTypeOf(targetType, endType)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelatedEntityRef_TargetEntityNotCompatible, "targetEntityRef"); } // Validation succeeded, initialize remaining state (_targetEntityRef is already initialized) _targetEnd = targetEnd; _sourceEnd = sourceEnd; } /// /// Retrieves the 'source' end of the relationship navigation satisfied by this related entity Ref /// internal RelationshipEndMember SourceEnd { get { return _sourceEnd; } } ////// Retrieves the 'target' end of the relationship navigation satisfied by this related entity Ref /// internal RelationshipEndMember TargetEnd { get { return _targetEnd; } } ////// Retrieves the entity Ref that is the result of navigating from the source to the target end of this related entity Ref /// internal DbExpression TargetEntityReference { get { return _targetEntityRef.Expression; } set { _targetEntityRef.Expression = value; } } } ////// Represents the construction of a new instance of a given type, including set and record types. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] public sealed class DbNewInstanceExpression : DbExpression { private IList_elements; private System.Collections.ObjectModel.ReadOnlyCollection _relatedEntityRefs; internal DbNewInstanceExpression(DbCommandTree cmdTree, TypeUsage type, IList args) : base(cmdTree, DbExpressionKind.NewInstance) { // // Ensure that the type is non-null, valid and not NullType // cmdTree.TypeHelper.CheckType(type); // // Type-specific validation // CollectionType collectionType = null; if( TypeHelpers.TryGetEdmType (type, out collectionType) && collectionType != null) { TypeUsage elementType = collectionType.TypeUsage; // // Is this an empty collection constructor? // if (null == args || 0 == args.Count) { _elements = new ExpressionList("Arguments", cmdTree, 0); } else { _elements = new ExpressionList("Arguments", cmdTree, elementType, args); } } else { EntityUtil.CheckArgumentNull(args, "args"); _elements = CreateStructuralArgumentList(cmdTree, type, type.EdmType as StructuralType, args); } this.ResultType = type; } internal DbNewInstanceExpression(DbCommandTree cmdTree, EntityType entityType, IList attributeValues, IList relationships) : base(cmdTree, DbExpressionKind.NewInstance) { EntityUtil.CheckArgumentNull(entityType, "entityType"); EntityUtil.CheckArgumentNull(attributeValues, "attributeValues"); EntityUtil.CheckArgumentNull(relationships, "relationships"); TypeUsage resultType = CommandTreeTypeHelper.CreateResultType(entityType); cmdTree.TypeHelper.CheckType(resultType, "entityType"); _elements = CreateStructuralArgumentList(cmdTree, resultType, entityType, attributeValues); if (relationships.Count > 0) { List relatedRefs = new List (relationships.Count); for (int idx = 0; idx < relationships.Count; idx++) { DbRelatedEntityRef relatedRef = relationships[idx]; EntityUtil.CheckArgumentNull(relatedRef, CommandTreeUtils.FormatIndex("relationships", idx)); // The target entity ref must be associated with the same command tree as this new instance expression if (!object.ReferenceEquals(relatedRef.TargetEntityReference.CommandTree, cmdTree)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_NewInstance_IncompatibleRelatedEntity_TargetEntityNotValid, CommandTreeUtils.FormatIndex("relationships", idx)); } // The source end type must be the same type or a supertype of the Entity instance type EntityTypeBase expectedSourceType = TypeHelpers.GetEdmType (relatedRef.SourceEnd.TypeUsage).ElementType; if (!entityType.EdmEquals(expectedSourceType) && !entityType.IsSubtypeOf(expectedSourceType)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_NewInstance_IncompatibleRelatedEntity_SourceTypeNotValid, CommandTreeUtils.FormatIndex("relationships", idx)); } relatedRefs.Add(relatedRef); } _relatedEntityRefs = relatedRefs.AsReadOnly(); } this.ResultType = resultType; } /// /// Gets an public IListlist that provides the property/column values or set elements for the new instance. /// Arguments { get { return _elements; } } /// /// The visitor pattern method for expression visitors that do not produce a result value. /// /// An instance of DbExpressionVisitor. ///public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } /// is null /// The visitor pattern method for expression visitors that produce a result value of a specific type. /// /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. ///The type of the result produced by ////// is null An instance of public override TResultType Accept. (DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } internal bool HasRelatedEntityReferences { get { return (_relatedEntityRefs != null); } } /// /// Gets the related entity references (if any) for an entity constructor. /// May be null if no related entities were specified - use the internal System.Collections.ObjectModel.ReadOnlyCollectionproperty to determine this. /// RelatedEntityReferences { get { return _relatedEntityRefs; } } private static IList CreateStructuralArgumentList(DbCommandTree cmdTree, TypeUsage type, StructuralType structType, IList args) { if (null == structType) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_NewInstance_StructuralTypeRequired, "type"); } if (structType.Members.Count < 1) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_NewInstance_CannotInstantiateMemberlessType(TypeHelpers.GetFullName(type)), "type"); } if (structType.Abstract) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_NewInstance_CannotInstantiateAbstractType(TypeHelpers.GetFullName(type)), "type"); } return new ExpressionList("Arguments", cmdTree, TypeHelpers.GetAllStructuralMembers(structType), args); } } /// /// Represents a (strongly typed) reference to a specific instance within a given entity set. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] public sealed class DbRefExpression : DbUnaryExpression { EntitySet _entitySet; internal DbRefExpression(DbCommandTree cmdTree, EntitySet entitySet, DbExpression refKeys, EntityType entityType) : base(cmdTree, DbExpressionKind.Ref) { EntityUtil.CheckArgumentNull(entitySet, "entitySet"); EntityUtil.CheckArgumentNull(refKeys, "refKeys"); CommandTreeTypeHelper.CheckType(entityType); cmdTree.TypeHelper.CheckEntitySet(entitySet); // // Verify that the specified return type of the Ref operation is actually in // the same hierarchy as the Entity type of the specified Entity set. // if (!TypeSemantics.IsValidPolymorphicCast(entitySet.ElementType, entityType)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Ref_PolymorphicArgRequired); } // // The Argument DbExpression must construct a set of values of the same types as the Key members of the Entity // The names of the columns in the record type constructed by the Argument are not important, only that the // number of columns is the same as the number of Key members and that for each Key member the corresponding // column (based on order) is of a promotable type. // To enforce this the ArgumentLink ExpressionLink's ExpectedType is initialized to a record type based on the // names and types of the Key members. Since the promotability check used in ExpressionLink will ignore the names // of the ExpectedType's columns, ExpressionLink will therefore enforce the required level of type correctness // on the argument expression both here when it's value is first set (by calling ArgumentLink.InitializeValue) // and subsequently when the value of the Argument property is set to a new value. // // Set the expected type to be the record type created based on the Key members // TypeUsage keyType = CommandTreeTypeHelper.CreateResultType(TypeHelpers.CreateKeyRowType(entitySet.ElementType, cmdTree.MetadataWorkspace)); this.ArgumentLink.SetExpectedType(keyType); // // Attempt to initialize the Argument to the specified DbExpression. // If the type is not promotable to the record type set above (i.e. does // not have the same number of columns, with the type of each corresponding // column promotable to the column type of the record's column, names ignored) // then the ExpressionLink will throw at this point. // this.ArgumentLink.InitializeValue(refKeys); cmdTree.TrackContainer(entitySet.EntityContainer); // Initialize the entitySet and result type properties. // The result type of the expression is Ref. _entitySet = entitySet; this.ResultType = CommandTreeTypeHelper.CreateReferenceResultType(entityType); } /// /// Gets the metadata for the entity set that contains the instance. /// public EntitySet EntitySet { get { return _entitySet; } } ////// The visitor pattern method for expression visitors that do not produce a result value. /// /// An instance of DbExpressionVisitor. ///public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } /// is null /// The visitor pattern method for expression visitors that produce a result value of a specific type. /// /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. ///The type of the result produced by ////// is null An instance of public override TResultType Accept. (DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } } /// /// Represents the retrieval of a given entity using the specified Ref. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Deref"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] public sealed class DbDerefExpression : DbUnaryExpression { internal DbDerefExpression(DbCommandTree cmdTree, DbExpression refExpr) : base(cmdTree, DbExpressionKind.Deref, refExpr) { // // Ensure that the operand is actually of a reference type. // EntityType entityType; if(!TypeHelpers.TryGetRefEntityType(this.Argument.ResultType, out entityType)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_DeRef_RefRequired, "Argument"); } // // Result Type is the element type of the reference type // this.ResultType = CommandTreeTypeHelper.CreateResultType(entityType); } ////// The visitor pattern method for expression visitors that do not produce a result value. /// /// An instance of DbExpressionVisitor. ///public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } /// is null /// The visitor pattern method for expression visitors that produce a result value of a specific type. /// /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. ///The type of the result produced by ////// is null An instance of public override TResultType Accept. (DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } } /// /// Represents a 'scan' of all elements of a given entity set. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] public sealed class DbScanExpression : DbExpression { private EntitySetBase _targetSet; internal DbScanExpression(DbCommandTree cmdTree, EntitySetBase entitySet) : base(cmdTree, DbExpressionKind.Scan) { cmdTree.TypeHelper.CheckEntitySet(entitySet); cmdTree.TrackContainer(entitySet.EntityContainer); _targetSet = entitySet; this.ResultType = CommandTreeTypeHelper.CreateCollectionResultType(entitySet.ElementType); } ////// Gets the metadata for the referenced entity or relationship set. /// public EntitySetBase Target { get { return _targetSet; } } ////// The visitor pattern method for expression visitors that do not produce a result value. /// /// An instance of DbExpressionVisitor. ///public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } /// is null /// The visitor pattern method for expression visitors that produce a result value of a specific type. /// /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. ///The type of the result produced by ////// is null An instance of public override TResultType Accept. (DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....], [....] //--------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Data.Common; using System.Data.Metadata.Edm; using System.Data.Common.CommandTrees.Internal; namespace System.Data.Common.CommandTrees { ////// Represents a constant value. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] public sealed class DbConstantExpression : DbExpression { private object _value; internal DbConstantExpression(DbCommandTree commandTree, object value) : base(commandTree, DbExpressionKind.Constant) { if (null == value) { throw EntityUtil.ArgumentNull("value"); } // // Check that typeof(value) is actually a valid constant (i.e. primitive) type // PrimitiveTypeKind primitiveTypeKind; if (!CommandTreeUtils.TryGetPrimtiveTypeKind(value.GetType(), out primitiveTypeKind)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Constant_InvalidType, "value"); } TypeUsage typeMeta = TypeHelpers.GetLiteralTypeUsage(primitiveTypeKind); // // Set the value // _value = value; this.ResultType = typeMeta; } internal DbConstantExpression(DbCommandTree commandTree, object value, TypeUsage constantType) : base(commandTree, DbExpressionKind.Constant) { // // Basic validation of constant value and constant type (non-null, read-only, etc) // EntityUtil.CheckArgumentNull(value, "value"); commandTree.TypeHelper.CheckType(constantType, "constantType"); // // Verify that constantType is a primitive type and that value is an instance of that primitive type // Note that the value is not validated against applicable facets (such as MaxLength for a string value), // this is left to the server. // PrimitiveType primitiveType; if (!TypeHelpers.TryGetEdmType(constantType, out primitiveType)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Constant_InvalidConstantType(constantType.ToString()), "constantType"); } PrimitiveTypeKind valueKind; if (!CommandTreeUtils.TryGetPrimtiveTypeKind(value.GetType(), out valueKind) || primitiveType.PrimitiveTypeKind != valueKind) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Constant_InvalidValueForType(constantType.ToString()), "value"); } // // Set the value // _value = value; this.ResultType = constantType; } /// /// Gets the constant value. /// public object Value { get { return _value; } } ////// The visitor pattern method for expression visitors that do not produce a result value. /// /// An instance of DbExpressionVisitor. ///public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } /// is null /// The visitor pattern method for expression visitors that produce a result value of a specific type. /// /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. ///The type of the result produced by ////// is null An instance of public override TResultType Accept. (DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } } /// /// Represents null. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] public sealed class DbNullExpression : DbExpression { internal DbNullExpression(DbCommandTree commandTree, TypeUsage type) : base(commandTree, DbExpressionKind.Null) { commandTree.TypeHelper.CheckType(type); this.ResultType = type; } ////// The visitor pattern method for expression visitors that do not produce a result value. /// /// An instance of DbExpressionVisitor. ///public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } /// is null /// The visitor pattern method for expression visitors that produce a result value of a specific type. /// /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. ///The type of the result produced by ////// is null An instance of public override TResultType Accept. (DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } } /// /// Represents a reference to a variable that is currently in scope. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] public sealed class DbVariableReferenceExpression : DbExpression { private string _name; internal DbVariableReferenceExpression(DbCommandTree cmdTree, TypeUsage type, string name) : base(cmdTree, DbExpressionKind.VariableReference) { if (string.IsNullOrEmpty(name)) { throw EntityUtil.ArgumentNull("name"); } // // Verify the type of the reference. NullType is not allowed in Var or Parameter references. // cmdTree.TypeHelper.CheckType(type); _name = name; this.ResultType = type; } ////// Gets the name of the referenced variable. /// public string VariableName { get { return _name; } } ////// The visitor pattern method for expression visitors that do not produce a result value. /// /// An instance of DbExpressionVisitor. ///public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } /// is null /// The visitor pattern method for expression visitors that produce a result value of a specific type. /// /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. ///The type of the result produced by ////// is null An instance of public override TResultType Accept. (DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } } /// /// Represents a reference to a parameter declared on the command tree that contains this expression. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] public sealed class DbParameterReferenceExpression : DbExpression { private string _name; internal DbParameterReferenceExpression(DbCommandTree cmdTree, TypeUsage type, string name) : base(cmdTree, DbExpressionKind.ParameterReference) { EntityUtil.CheckArgumentNull(name, "name"); // DbCommandTree.CreateParameterRefExpression should check that a parameter with the given name exists, // and DbCommandTree.AddParameter should have already verified that the name is valid, so this need only // be asserted here. Debug.Assert(DbCommandTree.IsValidParameterName(name), string.Format(CultureInfo.InvariantCulture, "Invalid parameter name passed to DbParameterReferenceExpression constructor: '{0}'", name)); // // Verify the type of the reference. NullType is not allowed in Var or Parameter references. // cmdTree.TypeHelper.CheckType(type); _name = name; this.ResultType = type; } ////// Gets the name of the referenced parameter. /// public string ParameterName { get { return _name; } } ////// The visitor pattern method for expression visitors that do not produce a result value. /// /// An instance of DbExpressionVisitor. ///public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } /// is null /// The visitor pattern method for expression visitors that produce a result value of a specific type. /// /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. ///The type of the result produced by ////// is null An instance of public override TResultType Accept. (DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } } /// /// Represents the retrieval of a static or instance property. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] public sealed class DbPropertyExpression : DbExpression { private EdmMember _property; private ExpressionLink _instance; private void InitializeFromMember(DbCommandTree tree, EdmMember member, DbExpression instance) { // // Validate the instance // if (null == instance) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Property_InstanceRequiredForInstance, "instance"); } TypeUsage instanceType = TypeUsage.Create(member.DeclaringType); _instance = new ExpressionLink("Instance", tree, instanceType, instance); Debug.Assert(!TypeSemantics.IsNullOrNullType(Helper.GetModelTypeUsage(member)), "EdmMember metadata has a TypeUsage of null or NullType"); _property = member; this.ResultType = Helper.GetModelTypeUsage(member); } internal DbPropertyExpression(DbCommandTree cmdTree, EdmProperty propertyInfo, DbExpression instance) : base(cmdTree, DbExpressionKind.Property) { // // Ensure that the property metadata is non-null and from the same metadata workspace and dataspace as the command tree. // cmdTree.TypeHelper.CheckMember(propertyInfo, "propertyInfo"); InitializeFromMember(cmdTree, propertyInfo, instance); } internal DbPropertyExpression(DbCommandTree cmdTree, RelationshipEndMember memberInfo, DbExpression instance) : base(cmdTree, DbExpressionKind.Property) { // // Ensure that the relationship end metadata is non-null and from the same metadata workspace and dataspace as the command tree. // cmdTree.TypeHelper.CheckMember(memberInfo, "memberInfo"); InitializeFromMember(cmdTree, memberInfo, instance); } internal DbPropertyExpression(DbCommandTree cmdTree, NavigationProperty propertyInfo, DbExpression instance) : base(cmdTree, DbExpressionKind.Property) { // // Ensure that the navigation property metadata is non-null and from the same metadata workspace and dataspace as the command tree. // cmdTree.TypeHelper.CheckMember(propertyInfo, "propertyInfo"); InitializeFromMember(cmdTree, propertyInfo, instance); } ////// Gets the property metadata for the property to retrieve. /// public EdmMember Property { get { return _property; } } ////// Gets or sets an ///that defines the instance from which the property should be retrieved. /// The expression is null ////// The expression is not associated with the DbPropertyExpression's command tree, /// or its result type is not equal or promotable to the type that defines the property /// public DbExpression Instance { get { return _instance.Expression; } /*CQT_PUBLIC_API(*/internal/*)*/ set { _instance.Expression = value; } } ////// The visitor pattern method for expression visitors that do not produce a result value. /// /// An instance of DbExpressionVisitor. ///public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } /// is null /// The visitor pattern method for expression visitors that produce a result value of a specific type. /// /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. ///The type of the result produced by ////// is null An instance of public override TResultType Accept. (DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } } /// /// Represents the invocation of a function. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] public sealed class DbFunctionExpression : DbExpression { private EdmFunction _functionInfo; private IList_args; private ExpressionLink _lambdaBody; internal DbFunctionExpression(DbCommandTree cmdTree, EdmFunction function, DbExpression lambdaBody, IList args) : base(cmdTree, DbExpressionKind.Function) { // // Ensure that the function metadata is non-null and from the same metadata workspace and dataspace as the command tree. // Lambda functions are not verified since all of their components (return type, parameter types) have already been // checked and because they have not been added to a metadata collection because they are not directly associated with // a particular metadata workspace. Iff a function is a Lambda function will the Lambda body argument be non-null. // if (null == lambdaBody) { cmdTree.TypeHelper.CheckFunction(function); } // // Non-composable functions or functions including command text are not permitted in expressions -- they can only be // executed independently // if (!function.IsComposableAttribute) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Function_NonComposableInExpression, "function"); } if (!String.IsNullOrEmpty(function.CommandTextAttribute)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Function_CommandTextInExpression, "function"); } // // Functions that return void are not allowed // if (null == function.ReturnParameter || TypeSemantics.IsNullOrNullType(function.ReturnParameter.TypeUsage)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Function_VoidResultInvalid, "function"); } // // Validate the arguments // EntityUtil.CheckArgumentNull(args, "args"); _args = new ExpressionList("Arguments", cmdTree, function.Parameters, args); _functionInfo = function; // // Is this a 'Lambda' function invocation? // if(lambdaBody != null) { _lambdaBody = new ExpressionLink("LambdaBody", cmdTree, lambdaBody); } this.ResultType = function.ReturnParameter.TypeUsage; } /// /// Gets the metadata for the function to invoke. /// public EdmFunction Function { get { return _functionInfo; } } ////// Gets an public IListlist that provides the arguments to the function. /// Arguments { get { return _args; } } /// /// Gets a Boolean value indicating whether or not the function to invoke is an inline function definition (Lambda function). /// /*CQT_PUBLIC_API(*/internal/*)*/ bool IsLambda { get { return _lambdaBody != null; } } ////// Gets the DbExpression that provides the Body of the referenced function if that function is a Lambda function /// /*CQT_PUBLIC_API(*/internal/*)*/ DbExpression LambdaBody { get { if (_lambdaBody != null) { return _lambdaBody.Expression; } return null; } set { if (null == _lambdaBody) { throw EntityUtil.NotSupported(System.Data.Entity.Strings.Cqt_Function_BodyOnlyValidForLambda); } _lambdaBody.Expression = value; } } ////// The visitor pattern method for expression visitors that do not produce a result value. /// /// An instance of DbExpressionVisitor. ///public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } /// is null /// The visitor pattern method for expression visitors that produce a result value of a specific type. /// /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. ///The type of the result produced by ////// is null An instance of public override TResultType Accept. (DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } #region Lambda function namespace and name internal static string LambdaFunctionNameSpace { get { return "System.Data.Common.CommandTrees.LambdaFunctions"; } } internal static string LambdaFunctionName { get { return "Lambda"; } } #endregion } #if METHOD_EXPRESSION /// /// Represents the invocation of a method. /// public sealed class MethodExpression : Expression { MethodMetadata m_methodInfo; IListm_args; ExpressionLink m_inst; internal MethodExpression(CommandTree cmdTree, MethodMetadata methodInfo, IList args, Expression instance) : base(cmdTree, ExpressionKind.Method) { // // Ensure that the property metadata is non-null and from the same metadata workspace and dataspace as the command tree. // cmdTree.TypeHelper.CheckMember(methodInfo, "method", "methodInfo"); // // Methods that return void are not allowed // if (cmdTree.TypeHelper.IsNullOrNullType(methodInfo.Type)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Method_VoidResultInvalid, "methodInfo"); } if (null == args) { throw EntityUtil.ArgumentNull("args"); } this.m_inst = new ExpressionLink("Instance", cmdTree); // // Validate the instance // if (methodInfo.IsStatic) { if (instance != null) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Method_InstanceInvalidForStatic, "instance"); } } else { if (null == instance) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Method_InstanceRequiredForInstance, "instance"); } this.m_inst.SetExpectedType(methodInfo.DefiningType); this.m_inst.InitializeValue(instance); } // // Validate the arguments // m_args = new ExpressionList("Arguments", cmdTree, methodInfo.Parameters, args); m_methodInfo = methodInfo; this.ResultType = methodInfo.Type; } /// /// Gets the metadata for the method to invoke. /// public MethodMetadata Method { get { return m_methodInfo; } } ////// Gets the expressions that provide the arguments to the method. /// public IListArguments { get { return m_args; } } /// /// Gets or sets an ///that defines the instance on which the method should be invoked. Must be null for instance methods. /// For static properties, Instance
will always be null, and attempting to set a new value will result /// in. /// The expression is null ///The method is static ////// The expression is not associated with the MethodExpression's command tree, /// or its result type is not equal or promotable to the type that defines the method /// public Expression Instance { get { return m_inst.Expression; } /*CQT_PUBLIC_API(*/internal/*)*/ set { if (this.m_methodInfo.IsStatic) { throw EntityUtil.NotSupported(System.Data.Entity.Strings.Cqt_Method_InstanceInvalidForStatic); } this.m_inst.Expression = value; } } ////// The visitor pattern method for expression visitors that do not produce a result value. /// /// An instance of ExpressionVisitor. ///public override void Accept(ExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } /// is null /// The visitor pattern method for expression visitors that produce a result value of a specific type. /// /// An instance of a typed ExpressionVisitor that produces a result value of type TResultType. ///The type of the result produced by ////// is null An instance of public override TResultType Accept. (DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } } #endif /// /// Represents the navigation of a (composition or association) relationship given the 'from' role, the 'to' role and an instance of the from role /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] public sealed class DbRelationshipNavigationExpression : DbExpression { private RelationshipType _relation; private RelationshipEndMember _fromRole; private RelationshipEndMember _toRole; private ExpressionLink _from; internal DbRelationshipNavigationExpression( DbCommandTree cmdTree, RelationshipEndMember fromEnd, RelationshipEndMember toEnd, DbExpression from) : base(cmdTree, DbExpressionKind.RelationshipNavigation) { // // Validate the relationship ends before use // this.CheckEnds(fromEnd, toEnd); RelationshipType relType = fromEnd.DeclaringType as RelationshipType; // // Ensure that the relation type is non-null and from the same metadata workspace as the command tree // CommandTreeTypeHelper.CheckType(relType); // // Validate that the 'to' relationship end is defined by the same relationship type as the 'from' end // if (!relType.Equals(toEnd.DeclaringType)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Factory_IncompatibleRelationEnds, "toEnd"); } // // Validation was successful so initialize members and verify the source expression against the expected type // _relation = relType; _fromRole = fromEnd; _toRole = toEnd; _from = new ExpressionLink("NavigationSource", cmdTree, GetExpectedInstanceType(fromEnd, from), from); this.ResultType = GetResultType(toEnd); } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal DbRelationshipNavigationExpression( DbCommandTree cmdTree, RelationshipType type, string fromEndName, string toEndName, DbExpression from) : base(cmdTree, DbExpressionKind.RelationshipNavigation) { // // Verify that the from and to relation end names are not null // EntityUtil.CheckArgumentNull(fromEndName, "fromEndName"); EntityUtil.CheckArgumentNull(toEndName, "toEndName"); // // Ensure that the relation type is non-null and from the same metadata workspace as the command tree // CommandTreeTypeHelper.CheckType(type); // // Retrieve the relation end properties with the specified 'from' and 'to' names // RelationshipEndMember fromEnd = DbRelationshipNavigationExpression.FindEnd(type.Members, fromEndName, "fromEndName"); RelationshipEndMember toEnd = DbRelationshipNavigationExpression.FindEnd(type.Members, toEndName, "toEndName"); // // Validate the retrieved relation end properties // this.CheckEnds(fromEnd, toEnd); // // Validation was successful so initialize members and verify the source expression against the expected type // _relation = type; _fromRole = fromEnd; _toRole = toEnd; _from = new ExpressionLink("NavigationSource", cmdTree, GetExpectedInstanceType(fromEnd, from), from); this.ResultType = GetResultType(toEnd); } ////// Gets the metadata for the relationship over which navigation occurs /// public RelationshipType Relationship { get { return _relation; } } ////// Gets the metadata for the relationship end to navigate from /// public RelationshipEndMember NavigateFrom { get { return _fromRole; } } ////// Gets the metadata for the relationship end to navigate to /// public RelationshipEndMember NavigateTo { get { return _toRole; } } ////// Gets or sets an ///that specifies the instance of the 'from' relationship end from which navigation should occur. /// The expression is null ////// The expression is not associated with the DbRelationshipNavigationExpression's command tree, /// or its result type is not equal or promotable to the reference type of the NavigateFrom property. /// ///public DbExpression NavigationSource { get { return _from.Expression; } /*CQT_PUBLIC_API(*/internal/*)*/ set { _from.Expression = value; } } /// /// The visitor pattern method for expression visitors that do not produce a result value. /// /// An instance of DbExpressionVisitor. ///public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } /// is null /// The visitor pattern method for expression visitors that produce a result value of a specific type. /// /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. ///The type of the result produced by ////// is null An instance of public override TResultType Accept. (DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } /// /// Retrieves a relation end property from a given enumerable collection of members, given the name of the end. /// /// The enumerable collection of members /// The name of the end to retrieve /// The variable name to specify if an exception must be thrown ///An RelationEndProperty instance that represents the relation end with the specified name ///If no relation end with the specified name exists [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal static RelationshipEndMember FindEnd(IEnumerablemembers, string endName, string varName) { foreach (EdmMember member in members) { RelationshipEndMember end = member as RelationshipEndMember; if (end != null && end.Name.Equals(endName, StringComparison.Ordinal)) { return end; } } throw EntityUtil.ArgumentOutOfRange(System.Data.Entity.Strings.Cqt_Factory_NoSuchRelationEnd, varName); } private static TypeUsage GetExpectedInstanceType(RelationshipEndMember end, DbExpression from) { TypeUsage endType = end.TypeUsage; if (!TypeSemantics.IsReferenceType(endType)) { // // The only relation end that is currently allowed to have a non-Reference type is the Child end of // a composition, in which case the end type must be an entity type. // // Debug.Assert(end.Relation.IsComposition && !end.IsParent && (end.Type is EntityType), "Relation end can only have non-Reference type if it is a Composition child end"); endType = TypeHelpers.CreateReferenceTypeUsage(TypeHelpers.GetEdmType (endType)); } TypeUsage retType = TypeHelpers.GetCommonTypeUsage(endType, from.ResultType); if (null == retType) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelNav_WrongSourceType(TypeHelpers.GetFullName(endType)), "from"); } return retType; } private static TypeUsage GetResultType(RelationshipEndMember end) { TypeUsage retType = end.TypeUsage; if (!TypeSemantics.IsReferenceType(retType)) { // // The only relation end that is currently allowed to have a non-Reference type is the Child end of // a composition, in which case the end type must be an entity type. // //Debug.Assert(end.Relation.IsComposition && !end.IsParent && (end.Type is EntityType), "Relation end can only have non-Reference type if it is a Composition child end"); retType = TypeHelpers.CreateReferenceTypeUsage(TypeHelpers.GetEdmType (retType)); } // // If the upper bound is not 1 the result type is a collection of the given type // if (RelationshipMultiplicity.Many == end.RelationshipMultiplicity) { retType = TypeHelpers.CreateCollectionTypeUsage(retType); } return retType; } private void CheckEnds(RelationshipEndMember fromEnd, RelationshipEndMember toEnd) { // // Ensure that the 'from' role metadata is non-null and from the same metadata workspace as the command tree // this.CommandTree.TypeHelper.CheckMember(fromEnd, "fromEnd"); // // Ensure that the 'to' role metadata is non-null and from the same metadata workspace as the command tree // this.CommandTree.TypeHelper.CheckMember(toEnd, "toEnd"); } } /// /// Encapsulates the result (represented as a Ref to the resulting Entity) of navigating from /// the specified source end of a relationship to the specified target end. This class is intended /// for use only with [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] internal sealed class DbRelatedEntityRef { private readonly RelationshipEndMember _sourceEnd; private readonly RelationshipEndMember _targetEnd; private ExpressionLink _targetEntityRef; //private DbExpression _targetEntityRef; internal DbRelatedEntityRef(DbCommandTree commandTree, RelationshipEndMember sourceEnd, RelationshipEndMember targetEnd, DbExpression targetEntityRef) { // Validate that the specified relationship ends are: // 1. Non-null // 2. From the same metadata workspace as that used by the command tree commandTree.TypeHelper.CheckMember(sourceEnd, "sourceEnd"); commandTree.TypeHelper.CheckMember(targetEnd, "targetEnd"); // Validate that the specified target entity ref is: // 1. Non-null // 2. Associated with this command tree _targetEntityRef = new ExpressionLink("TargetEntityReference", commandTree); _targetEntityRef.InitializeValue(targetEntityRef); // Validate that the specified source and target ends are: // 1. Declared by the same relationship type if (!object.ReferenceEquals(sourceEnd.DeclaringType, targetEnd.DeclaringType)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelatedEntityRef_TargetEndFromDifferentRelationship, "targetEnd"); } // 2. Not the same end if (object.ReferenceEquals(sourceEnd, targetEnd)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelatedEntityRef_TargetEndSameAsSourceEnd, "targetEnd"); } // Validate that the specified target end has multiplicity of at most one if (targetEnd.RelationshipMultiplicity != RelationshipMultiplicity.One && targetEnd.RelationshipMultiplicity != RelationshipMultiplicity.ZeroOrOne) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelatedEntityRef_TargetEndMustBeAtMostOne, "targetEnd"); } // Validate that the specified target entity ref actually has a ref result type if (!TypeSemantics.IsReferenceType(targetEntityRef.ResultType)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelatedEntityRef_TargetEntityNotRef, "targetEntityRef"); } // Validate that the specified target entity is of a type that can be reached by navigating to the specified relationship end EntityTypeBase endType = TypeHelpers.GetEdmType, where an 'owning' instance of that class /// represents the source Entity involved in the relationship navigation. /// Instances of DbRelatedEntityRef may be specified when creating a that /// constructs an Entity, allowing information about Entities that are related to the newly constructed Entity to be captured. /// (targetEnd.TypeUsage).ElementType; EntityTypeBase targetType = TypeHelpers.GetEdmType (targetEntityRef.ResultType).ElementType; if (!endType.EdmEquals(targetType) && !TypeSemantics.IsSubTypeOf(targetType, endType)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelatedEntityRef_TargetEntityNotCompatible, "targetEntityRef"); } // Validation succeeded, initialize remaining state (_targetEntityRef is already initialized) _targetEnd = targetEnd; _sourceEnd = sourceEnd; } /// /// Retrieves the 'source' end of the relationship navigation satisfied by this related entity Ref /// internal RelationshipEndMember SourceEnd { get { return _sourceEnd; } } ////// Retrieves the 'target' end of the relationship navigation satisfied by this related entity Ref /// internal RelationshipEndMember TargetEnd { get { return _targetEnd; } } ////// Retrieves the entity Ref that is the result of navigating from the source to the target end of this related entity Ref /// internal DbExpression TargetEntityReference { get { return _targetEntityRef.Expression; } set { _targetEntityRef.Expression = value; } } } ////// Represents the construction of a new instance of a given type, including set and record types. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] public sealed class DbNewInstanceExpression : DbExpression { private IList_elements; private System.Collections.ObjectModel.ReadOnlyCollection _relatedEntityRefs; internal DbNewInstanceExpression(DbCommandTree cmdTree, TypeUsage type, IList args) : base(cmdTree, DbExpressionKind.NewInstance) { // // Ensure that the type is non-null, valid and not NullType // cmdTree.TypeHelper.CheckType(type); // // Type-specific validation // CollectionType collectionType = null; if( TypeHelpers.TryGetEdmType (type, out collectionType) && collectionType != null) { TypeUsage elementType = collectionType.TypeUsage; // // Is this an empty collection constructor? // if (null == args || 0 == args.Count) { _elements = new ExpressionList("Arguments", cmdTree, 0); } else { _elements = new ExpressionList("Arguments", cmdTree, elementType, args); } } else { EntityUtil.CheckArgumentNull(args, "args"); _elements = CreateStructuralArgumentList(cmdTree, type, type.EdmType as StructuralType, args); } this.ResultType = type; } internal DbNewInstanceExpression(DbCommandTree cmdTree, EntityType entityType, IList attributeValues, IList relationships) : base(cmdTree, DbExpressionKind.NewInstance) { EntityUtil.CheckArgumentNull(entityType, "entityType"); EntityUtil.CheckArgumentNull(attributeValues, "attributeValues"); EntityUtil.CheckArgumentNull(relationships, "relationships"); TypeUsage resultType = CommandTreeTypeHelper.CreateResultType(entityType); cmdTree.TypeHelper.CheckType(resultType, "entityType"); _elements = CreateStructuralArgumentList(cmdTree, resultType, entityType, attributeValues); if (relationships.Count > 0) { List relatedRefs = new List (relationships.Count); for (int idx = 0; idx < relationships.Count; idx++) { DbRelatedEntityRef relatedRef = relationships[idx]; EntityUtil.CheckArgumentNull(relatedRef, CommandTreeUtils.FormatIndex("relationships", idx)); // The target entity ref must be associated with the same command tree as this new instance expression if (!object.ReferenceEquals(relatedRef.TargetEntityReference.CommandTree, cmdTree)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_NewInstance_IncompatibleRelatedEntity_TargetEntityNotValid, CommandTreeUtils.FormatIndex("relationships", idx)); } // The source end type must be the same type or a supertype of the Entity instance type EntityTypeBase expectedSourceType = TypeHelpers.GetEdmType (relatedRef.SourceEnd.TypeUsage).ElementType; if (!entityType.EdmEquals(expectedSourceType) && !entityType.IsSubtypeOf(expectedSourceType)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_NewInstance_IncompatibleRelatedEntity_SourceTypeNotValid, CommandTreeUtils.FormatIndex("relationships", idx)); } relatedRefs.Add(relatedRef); } _relatedEntityRefs = relatedRefs.AsReadOnly(); } this.ResultType = resultType; } /// /// Gets an public IListlist that provides the property/column values or set elements for the new instance. /// Arguments { get { return _elements; } } /// /// The visitor pattern method for expression visitors that do not produce a result value. /// /// An instance of DbExpressionVisitor. ///public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } /// is null /// The visitor pattern method for expression visitors that produce a result value of a specific type. /// /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. ///The type of the result produced by ////// is null An instance of public override TResultType Accept. (DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } internal bool HasRelatedEntityReferences { get { return (_relatedEntityRefs != null); } } /// /// Gets the related entity references (if any) for an entity constructor. /// May be null if no related entities were specified - use the internal System.Collections.ObjectModel.ReadOnlyCollectionproperty to determine this. /// RelatedEntityReferences { get { return _relatedEntityRefs; } } private static IList CreateStructuralArgumentList(DbCommandTree cmdTree, TypeUsage type, StructuralType structType, IList args) { if (null == structType) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_NewInstance_StructuralTypeRequired, "type"); } if (structType.Members.Count < 1) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_NewInstance_CannotInstantiateMemberlessType(TypeHelpers.GetFullName(type)), "type"); } if (structType.Abstract) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_NewInstance_CannotInstantiateAbstractType(TypeHelpers.GetFullName(type)), "type"); } return new ExpressionList("Arguments", cmdTree, TypeHelpers.GetAllStructuralMembers(structType), args); } } /// /// Represents a (strongly typed) reference to a specific instance within a given entity set. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] public sealed class DbRefExpression : DbUnaryExpression { EntitySet _entitySet; internal DbRefExpression(DbCommandTree cmdTree, EntitySet entitySet, DbExpression refKeys, EntityType entityType) : base(cmdTree, DbExpressionKind.Ref) { EntityUtil.CheckArgumentNull(entitySet, "entitySet"); EntityUtil.CheckArgumentNull(refKeys, "refKeys"); CommandTreeTypeHelper.CheckType(entityType); cmdTree.TypeHelper.CheckEntitySet(entitySet); // // Verify that the specified return type of the Ref operation is actually in // the same hierarchy as the Entity type of the specified Entity set. // if (!TypeSemantics.IsValidPolymorphicCast(entitySet.ElementType, entityType)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Ref_PolymorphicArgRequired); } // // The Argument DbExpression must construct a set of values of the same types as the Key members of the Entity // The names of the columns in the record type constructed by the Argument are not important, only that the // number of columns is the same as the number of Key members and that for each Key member the corresponding // column (based on order) is of a promotable type. // To enforce this the ArgumentLink ExpressionLink's ExpectedType is initialized to a record type based on the // names and types of the Key members. Since the promotability check used in ExpressionLink will ignore the names // of the ExpectedType's columns, ExpressionLink will therefore enforce the required level of type correctness // on the argument expression both here when it's value is first set (by calling ArgumentLink.InitializeValue) // and subsequently when the value of the Argument property is set to a new value. // // Set the expected type to be the record type created based on the Key members // TypeUsage keyType = CommandTreeTypeHelper.CreateResultType(TypeHelpers.CreateKeyRowType(entitySet.ElementType, cmdTree.MetadataWorkspace)); this.ArgumentLink.SetExpectedType(keyType); // // Attempt to initialize the Argument to the specified DbExpression. // If the type is not promotable to the record type set above (i.e. does // not have the same number of columns, with the type of each corresponding // column promotable to the column type of the record's column, names ignored) // then the ExpressionLink will throw at this point. // this.ArgumentLink.InitializeValue(refKeys); cmdTree.TrackContainer(entitySet.EntityContainer); // Initialize the entitySet and result type properties. // The result type of the expression is Ref. _entitySet = entitySet; this.ResultType = CommandTreeTypeHelper.CreateReferenceResultType(entityType); } /// /// Gets the metadata for the entity set that contains the instance. /// public EntitySet EntitySet { get { return _entitySet; } } ////// The visitor pattern method for expression visitors that do not produce a result value. /// /// An instance of DbExpressionVisitor. ///public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } /// is null /// The visitor pattern method for expression visitors that produce a result value of a specific type. /// /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. ///The type of the result produced by ////// is null An instance of public override TResultType Accept. (DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } } /// /// Represents the retrieval of a given entity using the specified Ref. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Deref"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] public sealed class DbDerefExpression : DbUnaryExpression { internal DbDerefExpression(DbCommandTree cmdTree, DbExpression refExpr) : base(cmdTree, DbExpressionKind.Deref, refExpr) { // // Ensure that the operand is actually of a reference type. // EntityType entityType; if(!TypeHelpers.TryGetRefEntityType(this.Argument.ResultType, out entityType)) { throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_DeRef_RefRequired, "Argument"); } // // Result Type is the element type of the reference type // this.ResultType = CommandTreeTypeHelper.CreateResultType(entityType); } ////// The visitor pattern method for expression visitors that do not produce a result value. /// /// An instance of DbExpressionVisitor. ///public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } /// is null /// The visitor pattern method for expression visitors that produce a result value of a specific type. /// /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. ///The type of the result produced by ////// is null An instance of public override TResultType Accept. (DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } } /// /// Represents a 'scan' of all elements of a given entity set. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] public sealed class DbScanExpression : DbExpression { private EntitySetBase _targetSet; internal DbScanExpression(DbCommandTree cmdTree, EntitySetBase entitySet) : base(cmdTree, DbExpressionKind.Scan) { cmdTree.TypeHelper.CheckEntitySet(entitySet); cmdTree.TrackContainer(entitySet.EntityContainer); _targetSet = entitySet; this.ResultType = CommandTreeTypeHelper.CreateCollectionResultType(entitySet.ElementType); } ////// Gets the metadata for the referenced entity or relationship set. /// public EntitySetBase Target { get { return _targetSet; } } ////// The visitor pattern method for expression visitors that do not produce a result value. /// /// An instance of DbExpressionVisitor. ///public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } /// is null /// The visitor pattern method for expression visitors that produce a result value of a specific type. /// /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. ///The type of the result produced by ////// is null An instance of public override TResultType Accept. (DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- _ConnectOverlappedAsyncResult.cs
- CfgSemanticTag.cs
- ImageMetadata.cs
- Matrix3DValueSerializer.cs
- DataConnectionHelper.cs
- ManualResetEvent.cs
- SerTrace.cs
- SimpleHandlerBuildProvider.cs
- ScalarConstant.cs
- Help.cs
- Material.cs
- PageContent.cs
- CompressionTracing.cs
- QilIterator.cs
- DefaultParameterValueAttribute.cs
- StaticFileHandler.cs
- CustomAttributeBuilder.cs
- ApplicationDirectory.cs
- BindingObserver.cs
- Style.cs
- TypeUtil.cs
- Popup.cs
- InteropExecutor.cs
- HtmlHistory.cs
- AppDomainResourcePerfCounters.cs
- TraceUtility.cs
- Sql8ConformanceChecker.cs
- DataSourceView.cs
- AudioLevelUpdatedEventArgs.cs
- BinaryFormatter.cs
- BinaryWriter.cs
- XMLUtil.cs
- SiteMap.cs
- HyperLinkStyle.cs
- CodeMemberField.cs
- SqlCacheDependencySection.cs
- HtmlTernaryTree.cs
- WindowsTab.cs
- XmlILConstructAnalyzer.cs
- CodeDirectoryCompiler.cs
- XmlSchemaImporter.cs
- VisualStyleInformation.cs
- ClientSideProviderDescription.cs
- SchemaHelper.cs
- TogglePattern.cs
- NotEqual.cs
- ConfigurationSchemaErrors.cs
- EdmValidator.cs
- TabControl.cs
- SoapMessage.cs
- XamlStackWriter.cs
- FontStretches.cs
- ColumnReorderedEventArgs.cs
- ContainerUtilities.cs
- AddingNewEventArgs.cs
- ThousandthOfEmRealPoints.cs
- CodeMethodInvokeExpression.cs
- FormatConvertedBitmap.cs
- EntityDataSourceView.cs
- InputLanguage.cs
- PlainXmlDeserializer.cs
- baseaxisquery.cs
- SafeNativeMethods.cs
- DrawingContextDrawingContextWalker.cs
- SimpleHandlerFactory.cs
- PersianCalendar.cs
- activationcontext.cs
- CapabilitiesSection.cs
- HashCodeCombiner.cs
- XhtmlBasicPanelAdapter.cs
- DefaultIfEmptyQueryOperator.cs
- InfoCardSymmetricAlgorithm.cs
- RootBuilder.cs
- DataTransferEventArgs.cs
- DataPager.cs
- ModuleBuilder.cs
- SchemaImporterExtensionsSection.cs
- BuildProviderCollection.cs
- ResourcePart.cs
- SecurityElement.cs
- CodeAttributeArgument.cs
- EntityContainer.cs
- DataErrorValidationRule.cs
- HealthMonitoringSection.cs
- BuildProvider.cs
- GroupedContextMenuStrip.cs
- DataServiceHost.cs
- StringConverter.cs
- ScriptReference.cs
- BasicBrowserDialog.designer.cs
- Claim.cs
- MetaData.cs
- PlainXmlWriter.cs
- SettingsAttributes.cs
- LinkUtilities.cs
- COM2DataTypeToManagedDataTypeConverter.cs
- Transform3D.cs
- ErrorProvider.cs
- Filter.cs
- SamlAuthorizationDecisionClaimResource.cs