Esempio n. 1
0
		[ResourceConsumption(ResourceScope.Assembly | ResourceScope.Machine)] // FindType method call.
		internal MappedFunction(MappedMetaModel model, FunctionMapping map, MethodInfo method)
		{
			this.model = model;
			this.map = map;
			this.method = method;
			this.rowTypes = _emptyTypes;

			if(map.Types.Count == 0 && this.method.ReturnType == typeof(IMultipleResults))
			{
				throw Error.NoResultTypesDeclaredForFunction(method.Name);
			}
			else if(map.Types.Count > 1 && this.method.ReturnType != typeof(IMultipleResults))
			{
				throw Error.TooManyResultTypesDeclaredForFunction(method.Name);
			}
			else if(map.Types.Count == 1 && this.method.ReturnType != typeof(IMultipleResults))
			{
				Type elementType = TypeSystem.GetElementType(method.ReturnType);
				this.rowTypes = new List<MetaType>(1) { this.GetMetaType(map.Types[0], elementType) }.AsReadOnly();
			}
			else if(map.Types.Count > 0)
			{
				List<MetaType> rowTypes = new List<MetaType>();
				foreach(TypeMapping rtm in map.Types)
				{
					Type elementType = model.FindType(rtm.Name);
					if(elementType == null)
					{
						throw Error.CouldNotFindElementTypeInModel(rtm.Name);
					}
					MetaType mt = this.GetMetaType(rtm, elementType);
					// Only add unique meta types
					if(!rowTypes.Contains(mt))
					{
						rowTypes.Add(mt);
					}
				}
				this.rowTypes = rowTypes.AsReadOnly();
			}
			else if(map.FunReturn != null)
			{
				this.returnParameter = new MappedReturnParameter(method.ReturnParameter, map.FunReturn);
			}

			// Parameters.
			ParameterInfo[] pis = this.method.GetParameters();
			if(pis.Length > 0)
			{
				List<MetaParameter> mps = new List<MetaParameter>(pis.Length);
				if(this.map.Parameters.Count != pis.Length)
				{
					throw Error.IncorrectNumberOfParametersMappedForMethod(this.map.MethodName);
				}
				for(int i = 0; i < pis.Length; i++)
				{
					mps.Add(new MappedParameter(pis[i], this.map.Parameters[i]));
				}
				this.parameters = mps.AsReadOnly();
			}
			else
			{
				this.parameters = _emptyParameters;
			}
		}
        internal static FunctionMapping ReadFunctionMapping(XmlReader reader) {
            System.Diagnostics.Debug.Assert(reader.NodeType == XmlNodeType.Element);
            if (!IsInNamespace(reader) || reader.LocalName != XmlMappingConstant.Function) {
                throw Error.UnexpectedElement(XmlMappingConstant.Function, String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName));
            } 

            ValidateAttributes(reader, new[] { 
                                               XmlMappingConstant.Name, 
                                               XmlMappingConstant.Method, 
                                               XmlMappingConstant.IsComposable
                                           });

            FunctionMapping fm = new FunctionMapping();
            fm.MethodName = RequiredAttribute(reader, XmlMappingConstant.Method);
            fm.Name = OptionalAttribute(reader, XmlMappingConstant.Name);
            fm.IsComposable = OptionalBoolAttribute(reader, XmlMappingConstant.IsComposable, false);

            if (!reader.IsEmptyElement) {
                reader.ReadStartElement();
                reader.MoveToContent();
                while (reader.NodeType != XmlNodeType.EndElement) {
                    if (reader.NodeType == XmlNodeType.Whitespace || !IsInNamespace(reader)) {
                        reader.Skip();
                        continue;
                    }
                    
                    switch (reader.LocalName) {
                        case XmlMappingConstant.Parameter:
                            fm.Parameters.Add(ReadParameterMapping(reader));
                            break;
                        case XmlMappingConstant.ElementType:
                            fm.Types.Add(ReadElementTypeMapping(null, reader));
                            break;
                        case XmlMappingConstant.Return:
                            fm.FunReturn = ReadReturnMapping(reader);
                            break;
                        default:
                            throw Error.UnrecognizedElement(String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName));
                    }
                    reader.MoveToContent();
                }
                reader.ReadEndElement();
            }
            else {
                // no content is okay
                reader.Skip();
            }

            return fm;
        }