Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / ndp / fx / src / DataEntity / System / Data / EntityModel / SchemaObjectModel / Function.cs / 1 / 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 SchemaElementLookUpTable Parameters
{
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 SchemaElementLookUpTable Parameters
{
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
- SecurityCriticalDataForSet.cs
- SoapIgnoreAttribute.cs
- dbdatarecord.cs
- DecimalKeyFrameCollection.cs
- IsolatedStorageFileStream.cs
- VideoDrawing.cs
- _CookieModule.cs
- RemoteWebConfigurationHost.cs
- XamlTreeBuilderBamlRecordWriter.cs
- RelationalExpressions.cs
- DesignerResources.cs
- PermissionListSet.cs
- DataGridViewToolTip.cs
- RangeContentEnumerator.cs
- SrgsElementList.cs
- AdapterUtil.cs
- CellCreator.cs
- ArrayExtension.cs
- XmlBaseWriter.cs
- TypedTableBaseExtensions.cs
- MarkupCompiler.cs
- BinHexDecoder.cs
- CaseInsensitiveHashCodeProvider.cs
- _SafeNetHandles.cs
- HttpProfileGroupBase.cs
- ContextInformation.cs
- BitmapCodecInfo.cs
- BrowserTree.cs
- WebCodeGenerator.cs
- SmtpSection.cs
- ListCollectionView.cs
- PageStatePersister.cs
- AbandonedMutexException.cs
- SiteMapDataSourceView.cs
- RadialGradientBrush.cs
- SchemaElement.cs
- ToolStripSystemRenderer.cs
- PaperSource.cs
- PerformanceCounterPermission.cs
- Setter.cs
- DateRangeEvent.cs
- CacheMemory.cs
- HtmlTextArea.cs
- TextRunCache.cs
- WebPartMenuStyle.cs
- BevelBitmapEffect.cs
- AuthenticationSection.cs
- JsonStringDataContract.cs
- ScaleTransform3D.cs
- ToolStripEditorManager.cs
- StreamWithDictionary.cs
- DtdParser.cs
- CngProperty.cs
- XmlSchemaAny.cs
- HttpProtocolImporter.cs
- SQLDateTime.cs
- TextTreeInsertElementUndoUnit.cs
- CssClassPropertyAttribute.cs
- WebChannelFactory.cs
- XPathDocument.cs
- ReadWriteSpinLock.cs
- XmlSchemaSimpleTypeUnion.cs
- EntityDataSourceWizardForm.cs
- XmlDataSourceView.cs
- EventLogException.cs
- EventsTab.cs
- TextSearch.cs
- CompositeActivityTypeDescriptor.cs
- MsmqOutputChannel.cs
- TargetConverter.cs
- RelationshipEndMember.cs
- MutexSecurity.cs
- WebBrowserHelper.cs
- XmlFormatExtensionPointAttribute.cs
- Utils.cs
- ResourceReferenceExpression.cs
- CodeAssignStatement.cs
- GACIdentityPermission.cs
- ResolveRequestResponseAsyncResult.cs
- URLIdentityPermission.cs
- ParseHttpDate.cs
- SessionStateContainer.cs
- SetterBaseCollection.cs
- RelationshipConstraintValidator.cs
- MenuItemStyleCollection.cs
- CustomSignedXml.cs
- ResolvedKeyFrameEntry.cs
- TraceListeners.cs
- TagPrefixAttribute.cs
- OrderedEnumerableRowCollection.cs
- EventLogLink.cs
- RSAPKCS1KeyExchangeFormatter.cs
- SystemParameters.cs
- TemplateControlBuildProvider.cs
- TemplateKey.cs
- SerializationInfoEnumerator.cs
- MutableAssemblyCacheEntry.cs
- FontNamesConverter.cs
- Emitter.cs
- PrefixQName.cs