Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / DataEntity / System / Data / EntityModel / SchemaObjectModel / Function.cs / 4 / Function.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; using System.Globalization; using System.Xml; using System.Xml.Schema; using System.Data; using System.IO; using System.Data.Metadata.Edm; using System.Data.Entity; namespace System.Data.EntityModel.SchemaObjectModel { ////// class representing the Schema element in the schema /// internal class Function : SchemaType { #region Instance Fields // if adding properties also add to InitializeObject()! private bool _isAggregate = false; private bool _isBuiltIn = false; private bool _isNiladicFunction = false; private bool _isComposable = true; private string _unresolvedEntitySet = null; private FunctionCommandText _commandText = null; private string _storeFunctionName = null; private SchemaType _type = null; private string _unresolvedType = null; // both are not specified private SchemaElementLookUpTable_parameters = null; private ReturnType _returnType = null; private CollectionKind _collectionKind = CollectionKind.None; private ParameterTypeSemantics _parameterTypeSemantics; private EntityContainer _container = null; // container is known only for function imports private EntityContainerEntitySet _entitySet = null; private string _schema; private string _functionStrongName; #endregion #region Static Fields private static System.Text.RegularExpressions.Regex s_typeParser = new System.Text.RegularExpressions.Regex(@"^(? ((Collection)|(Ref)))\s*\(\s*(? \S*)\s*\)$", System.Text.RegularExpressions.RegexOptions.Compiled); /// /// /// /// ///internal static TypeModifier RemoveTypeModifier(ref string type) { System.Text.RegularExpressions.Match match = s_typeParser.Match(type); if (match.Success) { type = match.Groups["typeName"].Value; switch (match.Groups["modifier"].Value) { case "Collection": return TypeModifier.Array; default: Debug.Assert(false, "Unexpected modifier: " + match.Groups["modifier"].Value); break; } } return TypeModifier.None; } #endregion #region Public Methods /// /// ctor for a schema function /// public Function(Schema parentElement) : base(parentElement) { } ////// ctor for a function import, which is scoped to the entity container /// /// Parent container; must not be null. protected Function(EntityContainer container) : base(container.Schema) { Debug.Assert(null != container); _container = container; // override defaults for function imports _isComposable = false; } #endregion #region Public Properties public bool IsAggregate { get { return _isAggregate; } internal set { _isAggregate = value; } } public bool IsBuiltIn { get { return _isBuiltIn; } internal set { _isBuiltIn = value; } } public bool IsNiladicFunction { get { return _isNiladicFunction; } internal set { _isNiladicFunction = value; } } public bool IsComposable { get { return _isComposable; } internal set { _isComposable = value; } } public string CommandText { get { if (_commandText != null) { return _commandText.CommandText; } return null; } } public ParameterTypeSemantics ParameterTypeSemantics { get { return _parameterTypeSemantics; } internal set { _parameterTypeSemantics = value; } } public string StoreFunctionName { get { return _storeFunctionName; } internal set { Debug.Assert(value != null, "StoreFunctionName should never be set null value"); _storeFunctionName = value; } } public SchemaType Type { get { if (null != this.ReturnType) { return this.ReturnType.Type; } else return this._type; } } public ReturnType ReturnType { get { return this._returnType; } } public SchemaElementLookUpTableParameters { get { if (_parameters == null) { _parameters = new SchemaElementLookUpTable (); } return _parameters; } } public CollectionKind CollectionKind { get { return _collectionKind; } internal set { _collectionKind = value; } } public override string Identity { get { if (String.IsNullOrEmpty(_functionStrongName)) { string name = this.FQName; System.Text.StringBuilder stringBuilder = new Text.StringBuilder(name); bool first = true; stringBuilder.Append('('); foreach (Parameter parameter in this.Parameters) { if (!first) { stringBuilder.Append(','); } else { first = false; } stringBuilder.Append(Helper.ToString(parameter.ParameterDirection)); stringBuilder.Append(' '); // we don't include the facets in the identity, since we are *not* // taking them into consideration inside the // RankFunctionParameters method of TypeResolver.cs stringBuilder.Append(parameter.Type.FQName); } stringBuilder.Append(')'); _functionStrongName = stringBuilder.ToString(); } return _functionStrongName; } } public virtual bool IsFunctionImport { get { return false; } } public EntityContainerEntitySet EntitySet { get { return _entitySet; } } public string DbSchema { get { return _schema; } } #endregion #region Protected Properties protected override bool HandleElement(XmlReader reader) { if (base.HandleElement(reader)) { return true; } else if (CanHandleElement(reader, XmlConstants.CommandText)) { HandleCommandTextFunctionElment(reader); return true; } else if (CanHandleElement(reader, XmlConstants.Parameter)) { HandleParameterElement(reader); return true; } else if (CanHandleElement(reader, XmlConstants.ReturnTypeElement)) { if (ParentElement.Schema.DataModel == SchemaDataModelOption.ProviderManifestModel) { HandleReturnTypeElement(reader); } else { SkipThroughElement(reader); } return true; } return false; } protected override bool HandleAttribute(XmlReader reader) { if (base.HandleAttribute(reader)) { return true; } else if (CanHandleAttribute(reader, XmlConstants.ReturnType)) { HandleReturnTypeAttribute(reader); return true; } else if (CanHandleAttribute(reader, XmlConstants.AggregateAttribute)) { HandleAggregateAttribute(reader); return true; } else if (CanHandleAttribute(reader, XmlConstants.BuiltInAttribute)) { HandleBuiltInAttribute(reader); return true; } else if (CanHandleAttribute(reader, XmlConstants.StoreFunctionName)) { HandleStoreFunctionNameAttribute(reader); return true; } else if (CanHandleAttribute(reader, XmlConstants.NiladicFunction)) { HandleNiladicFunctionAttribute(reader); return true; } else if (CanHandleAttribute(reader, XmlConstants.IsComposable)) { HandleIsComposableFunctionAttribute(reader); return true; } else if (CanHandleAttribute(reader, XmlConstants.ParameterTypeSemantics)) { HandleParameterTypeSemanticsAttribute(reader); return true; } else if (CanHandleAttribute(reader, XmlConstants.Schema)) { HandleDbSchemaAttribute(reader); return true; } else if (CanHandleAttribute(reader, XmlConstants.EntitySet)) { HandleEntitySetAttribute(reader); return true; } return false; } #endregion #region Internal Methods internal override void ResolveTopLevelNames() { base.ResolveTopLevelNames(); if (ReturnType != null) { Debug.Assert(Schema.DataModel == SchemaDataModelOption.ProviderManifestModel, "Only ProviderManifest will allow ReturnType elements"); ReturnType.ResolveTopLevelNames(); } Debug.Assert(this._type == null, "This must be resolved exactly once"); if (null != UnresolvedReturnType) { Debug.Assert(Schema.DataModel != SchemaDataModelOption.ProviderManifestModel, "ProviderManifest only has ReturnType as an element"); if (Schema.ResolveTypeName(this, UnresolvedReturnType, out _type)) { if (this.IsFunctionImport) { // must be either undefined, a collection of scalars, or a collection of entities if (!MeetsFunctionImportReturnTypeRequirements(_type)) { AddError(ErrorCode.FunctionImportUnsupportedReturnType, EdmSchemaErrorSeverity.Error, this, Schema.EdmVersion == XmlConstants.EdmVersionForV1 ? System.Data.Entity.Strings.FunctionImportWithUnsupportedReturnTypeV1(this.Name) : System.Data.Entity.Strings.FunctionImportWithUnsupportedReturnTypeV1_1(this.Name) ); } } else { if (!(_type is ScalarType)) { if (Schema.DataModel != SchemaDataModelOption.ProviderManifestModel) { AddError(ErrorCode.FunctionWithNonScalarTypeNotSupported, EdmSchemaErrorSeverity.Error, this, System.Data.Entity.Strings.FunctionWithNonScalarTypeNotSupported(_type.FQName, this.FQName)); } else { AddError(ErrorCode.FunctionWithNonScalarTypeNotSupported, EdmSchemaErrorSeverity.Error, this, System.Data.Entity.Strings.FunctionWithNonEdmTypeNotSupported(_type.FQName, this.FQName)); } } } } } if (IsFunctionImport) { Debug.Assert(null != _container, "function imports must know container"); // resolve entity set if (null == _entitySet && null != _unresolvedEntitySet) { _entitySet = _container.FindEntitySet(_unresolvedEntitySet); if (null == _entitySet) { AddError(ErrorCode.FunctionImportUnknownEntitySet, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.FunctionImportUnknownEntitySet(_unresolvedEntitySet, this.Name)); } } } foreach (Parameter parameter in this.Parameters) { parameter.ResolveTopLevelNames(); } } private bool MeetsFunctionImportReturnTypeRequirements(SchemaType type) { if (_type is ScalarType && _collectionKind == CollectionKind.Bag) return true; if (_type is SchemaEntityType && _collectionKind == CollectionKind.Bag) return true; if (Schema.EdmVersion == XmlConstants.EdmVersionForV1_1) { if (_type is ScalarType && _collectionKind == CollectionKind.None) return true; if (_type is SchemaEntityType && _collectionKind == CollectionKind.None) return true; if (_type is SchemaComplexType && _collectionKind == CollectionKind.None) return true; if (_type is SchemaComplexType && _collectionKind == CollectionKind.Bag) return true; } return false; } /// /// Perform local validation on function definition. /// internal override void Validate() { base.Validate(); if ( (null != _returnType && null != this._type)) { AddError(ErrorCode.AmbiguousFunctionReturnType, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.AmbiguousFunctionReturnType(this.Name, XmlConstants.ReturnType)); } if (_commandText != null) { _commandText.Validate(); } if (null == this.Type) { // only non-composable types can omit return type if (this.IsComposable) { AddError(ErrorCode.ComposableFunctionWithoutReturnType, EdmSchemaErrorSeverity.Error, Strings.ComposableFunctionMustDeclareReturnType); } } else { // non-composable functions may not declare a return type (except for function imports) if (!this.IsComposable && !this.IsFunctionImport) { AddError(ErrorCode.NonComposableFunctionWithReturnType, EdmSchemaErrorSeverity.Error, Strings.NonComposableFunctionMustNotDeclareReturnType); } } if (IsAggregate) { // Make sure that the function has exactly one parameter and that takes // a collection type if (Parameters.Count != 1) { AddError(ErrorCode.InvalidNumberOfParametersForAggregateFunction, EdmSchemaErrorSeverity.Error, this, System.Data.Entity.Strings.InvalidNumberOfParametersForAggregateFunction(FQName)); } else if (Parameters.GetElementAt(0).CollectionKind == CollectionKind.None) { // Since we have already checked that there should be exactly one parameter, it should be safe to get the // first parameter for the function Parameter param = Parameters.GetElementAt(0); AddError(ErrorCode.InvalidParameterTypeForAggregateFunction, EdmSchemaErrorSeverity.Error, this, System.Data.Entity.Strings.InvalidParameterTypeForAggregateFunction(param.Name, FQName)); } } if (!this.IsComposable) { // non-composable functions do not permit aggregate, build-in, or niladic attribute if (this.IsAggregate || this.IsNiladicFunction || this.IsBuiltIn) { AddError(ErrorCode.NonComposableFunctionAttributesNotValid, EdmSchemaErrorSeverity.Error, Strings.NonComposableFunctionHasDisallowedAttribute); } } if (null != this.CommandText) { // functions with command text are not composable if (this.IsComposable) { AddError(ErrorCode.ComposableFunctionWithCommandText, EdmSchemaErrorSeverity.Error, Strings.CommandTextFunctionsNotComposable); } // functions with command text cannot declare store function name if (null != this.StoreFunctionName) { AddError(ErrorCode.FunctionDeclaresCommandTextAndStoreFunctionName, EdmSchemaErrorSeverity.Error, Strings.CommandTextFunctionsCannotDeclareStoreFunctionName); } } if (this.IsFunctionImport) { // if entity type, verify specification of entity set and that the type is appropriate // for the entity set SchemaEntityType entityType = this.Type as SchemaEntityType; if (null != entityType) { if (null == this.EntitySet) { AddError(ErrorCode.FunctionImportReturnsEntitiesButDoesNotSpecifyEntitySet, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.FunctionImportReturnEntitiesButDoesNotSpecifyEntitySet(this.Name)); } else if (null != this.EntitySet.EntityType && !entityType.IsOfType(this.EntitySet.EntityType)) { AddError(ErrorCode.FunctionImportEntityTypeDoesNotMatchEntitySet, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.FunctionImportEntityTypeDoesNotMatchEntitySet( this.FQName, this.EntitySet.EntityType.FQName, this.EntitySet.Name, this.ParentElement.FQName)); } } if (null == entityType && null != EntitySet) { AddError(ErrorCode.FunctionImportSpecifiesEntitySetButDoesNotReturnEntityType, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.FunctionImportSpecifiesEntitySetButNotEntityType(this.Name, this.ParentElement.FQName)); } } } internal override SchemaElement Clone(SchemaElement parentElement) { Debug.Assert(IsFunctionImport, "we only support clone for FunctionImports"); Function function = new FunctionImportElement((EntityContainer)parentElement); function._isAggregate = _isAggregate; function._isBuiltIn = _isBuiltIn; function._isNiladicFunction = _isNiladicFunction; function._isComposable = _isComposable; function._entitySet = _entitySet; function._commandText = _commandText; function._storeFunctionName = _storeFunctionName; function._type = _type; function._returnType = _returnType; function._collectionKind = _collectionKind; function._parameterTypeSemantics = _parameterTypeSemantics; function._schema = _schema; function.Name = this.Name; // Clone all the parameters foreach (Parameter parameter in this.Parameters) { AddErrorKind error = function.Parameters.TryAdd((Parameter)parameter.Clone(function)); Debug.Assert(error == AddErrorKind.Succeeded, "Since we are cloning a validated function, this should never fail"); } return function; } #endregion #region Internal Properties ////// /// ///internal string UnresolvedReturnType { get { return _unresolvedType; } set { _unresolvedType = value; } } #endregion //Internal Properties #region Private Methods /// /// The method that is called when a DbSchema attribute is encountered. /// /// An XmlReader positioned at the Type attribute. private void HandleDbSchemaAttribute(XmlReader reader) { Debug.Assert(Schema.DataModel == SchemaDataModelOption.ProviderDataModel, "We shouldn't see this attribute unless we are parsing ssdl"); Debug.Assert(reader != null); _schema = reader.Value; } ////// Handler for the Version attribute /// /// xml reader currently positioned at Version attribute private void HandleAggregateAttribute(XmlReader reader) { Debug.Assert(reader != null); bool isAggregate = false; HandleBoolAttribute(reader, ref isAggregate); IsAggregate = isAggregate; } ////// Handler for the Namespace attribute /// /// xml reader currently positioned at Namespace attribute private void HandleBuiltInAttribute(XmlReader reader) { Debug.Assert(reader != null); bool isBuiltIn = false; HandleBoolAttribute(reader, ref isBuiltIn); IsBuiltIn = isBuiltIn; } ////// Handler for the Alias attribute /// /// xml reader currently positioned at Alias attribute private void HandleStoreFunctionNameAttribute(XmlReader reader) { Debug.Assert(reader != null); string value = reader.Value.ToString(); if (!String.IsNullOrEmpty(value)) { value = value.Trim(); StoreFunctionName = value; } } ////// Handler for the NiladicFunction attribute /// /// xml reader currently positioned at Namespace attribute private void HandleNiladicFunctionAttribute(XmlReader reader) { Debug.Assert(reader != null); bool isNiladicFunction = false; HandleBoolAttribute(reader, ref isNiladicFunction); IsNiladicFunction = isNiladicFunction; } ////// Handler for the IsComposable attribute /// /// xml reader currently positioned at Namespace attribute private void HandleIsComposableFunctionAttribute(XmlReader reader) { Debug.Assert(reader != null); bool isComposable = true; HandleBoolAttribute(reader, ref isComposable); IsComposable = isComposable; } private void HandleCommandTextFunctionElment(XmlReader reader) { Debug.Assert(reader != null); FunctionCommandText commandText = new FunctionCommandText(this); commandText.Parse(reader); _commandText = commandText; } private void HandleReturnTypeAttribute(XmlReader reader) { Debug.Assert(reader != null); Debug.Assert(UnresolvedReturnType == null); string type; if (!Utils.GetString(Schema, reader, out type)) return; switch (RemoveTypeModifier(ref type)) { case TypeModifier.Array: CollectionKind = CollectionKind.Bag; break; case TypeModifier.None: break; default: Debug.Assert(false, "RemoveTypeModifier already checks for this"); break; } if (!Utils.ValidateDottedName(Schema, reader, type)) return; UnresolvedReturnType = type; } ////// Handler for the Parameter Element /// /// xml reader currently positioned at Parameter Element private void HandleParameterElement(XmlReader reader) { Debug.Assert(reader != null); Parameter parameter = new Parameter(this); parameter.Parse(reader); Parameters.Add(parameter, true, Strings.ParameterNameAlreadyDefinedDuplicate); } ////// Handler for the ReturnType element /// /// xml reader currently positioned at ReturnType element private void HandleReturnTypeElement(XmlReader reader) { Debug.Assert(reader != null); ReturnType returnType = new ReturnType(this); returnType.Parse(reader); this._returnType = returnType; } ////// Handles ParameterTypeSemantics attribute /// /// private void HandleParameterTypeSemanticsAttribute(XmlReader reader) { Debug.Assert(reader != null); string value = reader.Value; if (String.IsNullOrEmpty(value)) { return; } value = value.Trim(); if (!String.IsNullOrEmpty(value)) { switch (value) { case "ExactMatchOnly": ParameterTypeSemantics = ParameterTypeSemantics.ExactMatchOnly; break; case "AllowImplicitPromotion": ParameterTypeSemantics = ParameterTypeSemantics.AllowImplicitPromotion; break; case "AllowImplicitConversion": ParameterTypeSemantics = ParameterTypeSemantics.AllowImplicitConversion; break; default: // don't try to use the name of the function, because we are still parsing the // attributes, and we may not be to the name attribute yet. AddError(ErrorCode.InvalidValueForParameterTypeSemantics, EdmSchemaErrorSeverity.Error, reader, System.Data.Entity.Strings.InvalidValueForParameterTypeSemanticsAttribute( value)); break; } } } ////// Handler for the EntitySet attribute /// /// xml reader currently positioned at EntitySet attribute private void HandleEntitySetAttribute(XmlReader reader) { Debug.Assert(reader != null); string entitySetName; if (Utils.GetString(Schema, reader, out entitySetName)) { _unresolvedEntitySet = entitySetName; } } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; using System.Globalization; using System.Xml; using System.Xml.Schema; using System.Data; using System.IO; using System.Data.Metadata.Edm; using System.Data.Entity; namespace System.Data.EntityModel.SchemaObjectModel { ////// class representing the Schema element in the schema /// internal class Function : SchemaType { #region Instance Fields // if adding properties also add to InitializeObject()! private bool _isAggregate = false; private bool _isBuiltIn = false; private bool _isNiladicFunction = false; private bool _isComposable = true; private string _unresolvedEntitySet = null; private FunctionCommandText _commandText = null; private string _storeFunctionName = null; private SchemaType _type = null; private string _unresolvedType = null; // both are not specified private SchemaElementLookUpTable_parameters = null; private ReturnType _returnType = null; private CollectionKind _collectionKind = CollectionKind.None; private ParameterTypeSemantics _parameterTypeSemantics; private EntityContainer _container = null; // container is known only for function imports private EntityContainerEntitySet _entitySet = null; private string _schema; private string _functionStrongName; #endregion #region Static Fields private static System.Text.RegularExpressions.Regex s_typeParser = new System.Text.RegularExpressions.Regex(@"^(? ((Collection)|(Ref)))\s*\(\s*(? \S*)\s*\)$", System.Text.RegularExpressions.RegexOptions.Compiled); /// /// /// /// ///internal static TypeModifier RemoveTypeModifier(ref string type) { System.Text.RegularExpressions.Match match = s_typeParser.Match(type); if (match.Success) { type = match.Groups["typeName"].Value; switch (match.Groups["modifier"].Value) { case "Collection": return TypeModifier.Array; default: Debug.Assert(false, "Unexpected modifier: " + match.Groups["modifier"].Value); break; } } return TypeModifier.None; } #endregion #region Public Methods /// /// ctor for a schema function /// public Function(Schema parentElement) : base(parentElement) { } ////// ctor for a function import, which is scoped to the entity container /// /// Parent container; must not be null. protected Function(EntityContainer container) : base(container.Schema) { Debug.Assert(null != container); _container = container; // override defaults for function imports _isComposable = false; } #endregion #region Public Properties public bool IsAggregate { get { return _isAggregate; } internal set { _isAggregate = value; } } public bool IsBuiltIn { get { return _isBuiltIn; } internal set { _isBuiltIn = value; } } public bool IsNiladicFunction { get { return _isNiladicFunction; } internal set { _isNiladicFunction = value; } } public bool IsComposable { get { return _isComposable; } internal set { _isComposable = value; } } public string CommandText { get { if (_commandText != null) { return _commandText.CommandText; } return null; } } public ParameterTypeSemantics ParameterTypeSemantics { get { return _parameterTypeSemantics; } internal set { _parameterTypeSemantics = value; } } public string StoreFunctionName { get { return _storeFunctionName; } internal set { Debug.Assert(value != null, "StoreFunctionName should never be set null value"); _storeFunctionName = value; } } public SchemaType Type { get { if (null != this.ReturnType) { return this.ReturnType.Type; } else return this._type; } } public ReturnType ReturnType { get { return this._returnType; } } public SchemaElementLookUpTableParameters { get { if (_parameters == null) { _parameters = new SchemaElementLookUpTable (); } return _parameters; } } public CollectionKind CollectionKind { get { return _collectionKind; } internal set { _collectionKind = value; } } public override string Identity { get { if (String.IsNullOrEmpty(_functionStrongName)) { string name = this.FQName; System.Text.StringBuilder stringBuilder = new Text.StringBuilder(name); bool first = true; stringBuilder.Append('('); foreach (Parameter parameter in this.Parameters) { if (!first) { stringBuilder.Append(','); } else { first = false; } stringBuilder.Append(Helper.ToString(parameter.ParameterDirection)); stringBuilder.Append(' '); // we don't include the facets in the identity, since we are *not* // taking them into consideration inside the // RankFunctionParameters method of TypeResolver.cs stringBuilder.Append(parameter.Type.FQName); } stringBuilder.Append(')'); _functionStrongName = stringBuilder.ToString(); } return _functionStrongName; } } public virtual bool IsFunctionImport { get { return false; } } public EntityContainerEntitySet EntitySet { get { return _entitySet; } } public string DbSchema { get { return _schema; } } #endregion #region Protected Properties protected override bool HandleElement(XmlReader reader) { if (base.HandleElement(reader)) { return true; } else if (CanHandleElement(reader, XmlConstants.CommandText)) { HandleCommandTextFunctionElment(reader); return true; } else if (CanHandleElement(reader, XmlConstants.Parameter)) { HandleParameterElement(reader); return true; } else if (CanHandleElement(reader, XmlConstants.ReturnTypeElement)) { if (ParentElement.Schema.DataModel == SchemaDataModelOption.ProviderManifestModel) { HandleReturnTypeElement(reader); } else { SkipThroughElement(reader); } return true; } return false; } protected override bool HandleAttribute(XmlReader reader) { if (base.HandleAttribute(reader)) { return true; } else if (CanHandleAttribute(reader, XmlConstants.ReturnType)) { HandleReturnTypeAttribute(reader); return true; } else if (CanHandleAttribute(reader, XmlConstants.AggregateAttribute)) { HandleAggregateAttribute(reader); return true; } else if (CanHandleAttribute(reader, XmlConstants.BuiltInAttribute)) { HandleBuiltInAttribute(reader); return true; } else if (CanHandleAttribute(reader, XmlConstants.StoreFunctionName)) { HandleStoreFunctionNameAttribute(reader); return true; } else if (CanHandleAttribute(reader, XmlConstants.NiladicFunction)) { HandleNiladicFunctionAttribute(reader); return true; } else if (CanHandleAttribute(reader, XmlConstants.IsComposable)) { HandleIsComposableFunctionAttribute(reader); return true; } else if (CanHandleAttribute(reader, XmlConstants.ParameterTypeSemantics)) { HandleParameterTypeSemanticsAttribute(reader); return true; } else if (CanHandleAttribute(reader, XmlConstants.Schema)) { HandleDbSchemaAttribute(reader); return true; } else if (CanHandleAttribute(reader, XmlConstants.EntitySet)) { HandleEntitySetAttribute(reader); return true; } return false; } #endregion #region Internal Methods internal override void ResolveTopLevelNames() { base.ResolveTopLevelNames(); if (ReturnType != null) { Debug.Assert(Schema.DataModel == SchemaDataModelOption.ProviderManifestModel, "Only ProviderManifest will allow ReturnType elements"); ReturnType.ResolveTopLevelNames(); } Debug.Assert(this._type == null, "This must be resolved exactly once"); if (null != UnresolvedReturnType) { Debug.Assert(Schema.DataModel != SchemaDataModelOption.ProviderManifestModel, "ProviderManifest only has ReturnType as an element"); if (Schema.ResolveTypeName(this, UnresolvedReturnType, out _type)) { if (this.IsFunctionImport) { // must be either undefined, a collection of scalars, or a collection of entities if (!MeetsFunctionImportReturnTypeRequirements(_type)) { AddError(ErrorCode.FunctionImportUnsupportedReturnType, EdmSchemaErrorSeverity.Error, this, Schema.EdmVersion == XmlConstants.EdmVersionForV1 ? System.Data.Entity.Strings.FunctionImportWithUnsupportedReturnTypeV1(this.Name) : System.Data.Entity.Strings.FunctionImportWithUnsupportedReturnTypeV1_1(this.Name) ); } } else { if (!(_type is ScalarType)) { if (Schema.DataModel != SchemaDataModelOption.ProviderManifestModel) { AddError(ErrorCode.FunctionWithNonScalarTypeNotSupported, EdmSchemaErrorSeverity.Error, this, System.Data.Entity.Strings.FunctionWithNonScalarTypeNotSupported(_type.FQName, this.FQName)); } else { AddError(ErrorCode.FunctionWithNonScalarTypeNotSupported, EdmSchemaErrorSeverity.Error, this, System.Data.Entity.Strings.FunctionWithNonEdmTypeNotSupported(_type.FQName, this.FQName)); } } } } } if (IsFunctionImport) { Debug.Assert(null != _container, "function imports must know container"); // resolve entity set if (null == _entitySet && null != _unresolvedEntitySet) { _entitySet = _container.FindEntitySet(_unresolvedEntitySet); if (null == _entitySet) { AddError(ErrorCode.FunctionImportUnknownEntitySet, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.FunctionImportUnknownEntitySet(_unresolvedEntitySet, this.Name)); } } } foreach (Parameter parameter in this.Parameters) { parameter.ResolveTopLevelNames(); } } private bool MeetsFunctionImportReturnTypeRequirements(SchemaType type) { if (_type is ScalarType && _collectionKind == CollectionKind.Bag) return true; if (_type is SchemaEntityType && _collectionKind == CollectionKind.Bag) return true; if (Schema.EdmVersion == XmlConstants.EdmVersionForV1_1) { if (_type is ScalarType && _collectionKind == CollectionKind.None) return true; if (_type is SchemaEntityType && _collectionKind == CollectionKind.None) return true; if (_type is SchemaComplexType && _collectionKind == CollectionKind.None) return true; if (_type is SchemaComplexType && _collectionKind == CollectionKind.Bag) return true; } return false; } /// /// Perform local validation on function definition. /// internal override void Validate() { base.Validate(); if ( (null != _returnType && null != this._type)) { AddError(ErrorCode.AmbiguousFunctionReturnType, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.AmbiguousFunctionReturnType(this.Name, XmlConstants.ReturnType)); } if (_commandText != null) { _commandText.Validate(); } if (null == this.Type) { // only non-composable types can omit return type if (this.IsComposable) { AddError(ErrorCode.ComposableFunctionWithoutReturnType, EdmSchemaErrorSeverity.Error, Strings.ComposableFunctionMustDeclareReturnType); } } else { // non-composable functions may not declare a return type (except for function imports) if (!this.IsComposable && !this.IsFunctionImport) { AddError(ErrorCode.NonComposableFunctionWithReturnType, EdmSchemaErrorSeverity.Error, Strings.NonComposableFunctionMustNotDeclareReturnType); } } if (IsAggregate) { // Make sure that the function has exactly one parameter and that takes // a collection type if (Parameters.Count != 1) { AddError(ErrorCode.InvalidNumberOfParametersForAggregateFunction, EdmSchemaErrorSeverity.Error, this, System.Data.Entity.Strings.InvalidNumberOfParametersForAggregateFunction(FQName)); } else if (Parameters.GetElementAt(0).CollectionKind == CollectionKind.None) { // Since we have already checked that there should be exactly one parameter, it should be safe to get the // first parameter for the function Parameter param = Parameters.GetElementAt(0); AddError(ErrorCode.InvalidParameterTypeForAggregateFunction, EdmSchemaErrorSeverity.Error, this, System.Data.Entity.Strings.InvalidParameterTypeForAggregateFunction(param.Name, FQName)); } } if (!this.IsComposable) { // non-composable functions do not permit aggregate, build-in, or niladic attribute if (this.IsAggregate || this.IsNiladicFunction || this.IsBuiltIn) { AddError(ErrorCode.NonComposableFunctionAttributesNotValid, EdmSchemaErrorSeverity.Error, Strings.NonComposableFunctionHasDisallowedAttribute); } } if (null != this.CommandText) { // functions with command text are not composable if (this.IsComposable) { AddError(ErrorCode.ComposableFunctionWithCommandText, EdmSchemaErrorSeverity.Error, Strings.CommandTextFunctionsNotComposable); } // functions with command text cannot declare store function name if (null != this.StoreFunctionName) { AddError(ErrorCode.FunctionDeclaresCommandTextAndStoreFunctionName, EdmSchemaErrorSeverity.Error, Strings.CommandTextFunctionsCannotDeclareStoreFunctionName); } } if (this.IsFunctionImport) { // if entity type, verify specification of entity set and that the type is appropriate // for the entity set SchemaEntityType entityType = this.Type as SchemaEntityType; if (null != entityType) { if (null == this.EntitySet) { AddError(ErrorCode.FunctionImportReturnsEntitiesButDoesNotSpecifyEntitySet, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.FunctionImportReturnEntitiesButDoesNotSpecifyEntitySet(this.Name)); } else if (null != this.EntitySet.EntityType && !entityType.IsOfType(this.EntitySet.EntityType)) { AddError(ErrorCode.FunctionImportEntityTypeDoesNotMatchEntitySet, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.FunctionImportEntityTypeDoesNotMatchEntitySet( this.FQName, this.EntitySet.EntityType.FQName, this.EntitySet.Name, this.ParentElement.FQName)); } } if (null == entityType && null != EntitySet) { AddError(ErrorCode.FunctionImportSpecifiesEntitySetButDoesNotReturnEntityType, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.FunctionImportSpecifiesEntitySetButNotEntityType(this.Name, this.ParentElement.FQName)); } } } internal override SchemaElement Clone(SchemaElement parentElement) { Debug.Assert(IsFunctionImport, "we only support clone for FunctionImports"); Function function = new FunctionImportElement((EntityContainer)parentElement); function._isAggregate = _isAggregate; function._isBuiltIn = _isBuiltIn; function._isNiladicFunction = _isNiladicFunction; function._isComposable = _isComposable; function._entitySet = _entitySet; function._commandText = _commandText; function._storeFunctionName = _storeFunctionName; function._type = _type; function._returnType = _returnType; function._collectionKind = _collectionKind; function._parameterTypeSemantics = _parameterTypeSemantics; function._schema = _schema; function.Name = this.Name; // Clone all the parameters foreach (Parameter parameter in this.Parameters) { AddErrorKind error = function.Parameters.TryAdd((Parameter)parameter.Clone(function)); Debug.Assert(error == AddErrorKind.Succeeded, "Since we are cloning a validated function, this should never fail"); } return function; } #endregion #region Internal Properties ////// /// ///internal string UnresolvedReturnType { get { return _unresolvedType; } set { _unresolvedType = value; } } #endregion //Internal Properties #region Private Methods /// /// The method that is called when a DbSchema attribute is encountered. /// /// An XmlReader positioned at the Type attribute. private void HandleDbSchemaAttribute(XmlReader reader) { Debug.Assert(Schema.DataModel == SchemaDataModelOption.ProviderDataModel, "We shouldn't see this attribute unless we are parsing ssdl"); Debug.Assert(reader != null); _schema = reader.Value; } ////// Handler for the Version attribute /// /// xml reader currently positioned at Version attribute private void HandleAggregateAttribute(XmlReader reader) { Debug.Assert(reader != null); bool isAggregate = false; HandleBoolAttribute(reader, ref isAggregate); IsAggregate = isAggregate; } ////// Handler for the Namespace attribute /// /// xml reader currently positioned at Namespace attribute private void HandleBuiltInAttribute(XmlReader reader) { Debug.Assert(reader != null); bool isBuiltIn = false; HandleBoolAttribute(reader, ref isBuiltIn); IsBuiltIn = isBuiltIn; } ////// Handler for the Alias attribute /// /// xml reader currently positioned at Alias attribute private void HandleStoreFunctionNameAttribute(XmlReader reader) { Debug.Assert(reader != null); string value = reader.Value.ToString(); if (!String.IsNullOrEmpty(value)) { value = value.Trim(); StoreFunctionName = value; } } ////// Handler for the NiladicFunction attribute /// /// xml reader currently positioned at Namespace attribute private void HandleNiladicFunctionAttribute(XmlReader reader) { Debug.Assert(reader != null); bool isNiladicFunction = false; HandleBoolAttribute(reader, ref isNiladicFunction); IsNiladicFunction = isNiladicFunction; } ////// Handler for the IsComposable attribute /// /// xml reader currently positioned at Namespace attribute private void HandleIsComposableFunctionAttribute(XmlReader reader) { Debug.Assert(reader != null); bool isComposable = true; HandleBoolAttribute(reader, ref isComposable); IsComposable = isComposable; } private void HandleCommandTextFunctionElment(XmlReader reader) { Debug.Assert(reader != null); FunctionCommandText commandText = new FunctionCommandText(this); commandText.Parse(reader); _commandText = commandText; } private void HandleReturnTypeAttribute(XmlReader reader) { Debug.Assert(reader != null); Debug.Assert(UnresolvedReturnType == null); string type; if (!Utils.GetString(Schema, reader, out type)) return; switch (RemoveTypeModifier(ref type)) { case TypeModifier.Array: CollectionKind = CollectionKind.Bag; break; case TypeModifier.None: break; default: Debug.Assert(false, "RemoveTypeModifier already checks for this"); break; } if (!Utils.ValidateDottedName(Schema, reader, type)) return; UnresolvedReturnType = type; } ////// Handler for the Parameter Element /// /// xml reader currently positioned at Parameter Element private void HandleParameterElement(XmlReader reader) { Debug.Assert(reader != null); Parameter parameter = new Parameter(this); parameter.Parse(reader); Parameters.Add(parameter, true, Strings.ParameterNameAlreadyDefinedDuplicate); } ////// Handler for the ReturnType element /// /// xml reader currently positioned at ReturnType element private void HandleReturnTypeElement(XmlReader reader) { Debug.Assert(reader != null); ReturnType returnType = new ReturnType(this); returnType.Parse(reader); this._returnType = returnType; } ////// Handles ParameterTypeSemantics attribute /// /// private void HandleParameterTypeSemanticsAttribute(XmlReader reader) { Debug.Assert(reader != null); string value = reader.Value; if (String.IsNullOrEmpty(value)) { return; } value = value.Trim(); if (!String.IsNullOrEmpty(value)) { switch (value) { case "ExactMatchOnly": ParameterTypeSemantics = ParameterTypeSemantics.ExactMatchOnly; break; case "AllowImplicitPromotion": ParameterTypeSemantics = ParameterTypeSemantics.AllowImplicitPromotion; break; case "AllowImplicitConversion": ParameterTypeSemantics = ParameterTypeSemantics.AllowImplicitConversion; break; default: // don't try to use the name of the function, because we are still parsing the // attributes, and we may not be to the name attribute yet. AddError(ErrorCode.InvalidValueForParameterTypeSemantics, EdmSchemaErrorSeverity.Error, reader, System.Data.Entity.Strings.InvalidValueForParameterTypeSemanticsAttribute( value)); break; } } } ////// Handler for the EntitySet attribute /// /// xml reader currently positioned at EntitySet attribute private void HandleEntitySetAttribute(XmlReader reader) { Debug.Assert(reader != null); string entitySetName; if (Utils.GetString(Schema, reader, out entitySetName)) { _unresolvedEntitySet = entitySetName; } } #endregion } } // 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
- BindingExpression.cs
- TreeViewAutomationPeer.cs
- WizardStepCollectionEditor.cs
- Rotation3DAnimationUsingKeyFrames.cs
- SyndicationSerializer.cs
- DataGridViewCellLinkedList.cs
- InstanceContextManager.cs
- DataPagerFieldCollection.cs
- Hyperlink.cs
- DSASignatureDeformatter.cs
- UnsafeNativeMethodsTablet.cs
- PartitionedDataSource.cs
- FileSystemWatcher.cs
- OpenTypeLayoutCache.cs
- LazyTextWriterCreator.cs
- PublisherMembershipCondition.cs
- GuidConverter.cs
- XmlSerializationWriter.cs
- TraceEventCache.cs
- MDIClient.cs
- GroupBoxAutomationPeer.cs
- MD5.cs
- RectangleGeometry.cs
- WebPartVerb.cs
- LayoutEngine.cs
- ScriptBehaviorDescriptor.cs
- ResourceManager.cs
- EmulateRecognizeCompletedEventArgs.cs
- BooleanFunctions.cs
- _PooledStream.cs
- MemberJoinTreeNode.cs
- HostingEnvironmentException.cs
- ShaperBuffers.cs
- ADRoleFactory.cs
- TimeZoneNotFoundException.cs
- Knowncolors.cs
- MembershipPasswordException.cs
- TextContainer.cs
- SubclassTypeValidatorAttribute.cs
- SystemParameters.cs
- XmlWriterSettings.cs
- Stream.cs
- StreamInfo.cs
- TextTreeRootTextBlock.cs
- Int32Storage.cs
- ListItemCollection.cs
- GPPOINTF.cs
- TaskCanceledException.cs
- SqlClientFactory.cs
- ZipIOLocalFileBlock.cs
- XmlSerializerSection.cs
- AvTrace.cs
- HwndSubclass.cs
- ReflectEventDescriptor.cs
- Renderer.cs
- PaperSize.cs
- WindowsFormsSynchronizationContext.cs
- NoResizeHandleGlyph.cs
- MarkupExtensionParser.cs
- MenuItemStyleCollection.cs
- ItemAutomationPeer.cs
- TdsParameterSetter.cs
- PlanCompiler.cs
- BamlVersionHeader.cs
- ThicknessConverter.cs
- ColumnClickEvent.cs
- Oid.cs
- AddInContractAttribute.cs
- FixUpCollection.cs
- AvTraceFormat.cs
- ResXResourceSet.cs
- FileAuthorizationModule.cs
- AttributeCollection.cs
- TagPrefixCollection.cs
- DataTemplateSelector.cs
- DrawingGroupDrawingContext.cs
- ItemMap.cs
- TableItemPattern.cs
- KnownTypeDataContractResolver.cs
- XmlUtf8RawTextWriter.cs
- SafeThreadHandle.cs
- EntityContainerEmitter.cs
- PerformanceCounterPermissionAttribute.cs
- PropertyPushdownHelper.cs
- MSAAWinEventWrap.cs
- MultipleViewProviderWrapper.cs
- ThrowHelper.cs
- PolicyLevel.cs
- WebPartDisplayMode.cs
- HttpClientCertificate.cs
- MetricEntry.cs
- X509CertificateInitiatorClientCredential.cs
- DataGridRowsPresenter.cs
- Selection.cs
- VirtualizedItemPattern.cs
- ImageClickEventArgs.cs
- NullableBoolConverter.cs
- Translator.cs
- DiscardableAttribute.cs
- Activator.cs