Beispiel #1
0
 internal virtual SqlStoredProcedureCall VisitStoredProcedureCall(SqlStoredProcedureCall spc) {
     for (int i = 0, n = spc.Arguments.Count; i < n; i++) {
         spc.Arguments[i] = this.VisitExpression(spc.Arguments[i]);
     }
     spc.Projection = this.VisitExpression(spc.Projection);
     for (int i = 0, n = spc.Columns.Count; i < n; i++) {
         spc.Columns[i] = (SqlUserColumn) this.Visit(spc.Columns[i]);
     }
     return spc;
 }
		/// <summary>
		/// Translate a call to a stored procedure
		/// </summary>             
		private SqlNode TranslateStoredProcedureCall(MethodCallExpression mce, MetaFunction function)
		{
			if(!_outerNode)
			{
				throw Error.SprocsCannotBeComposed();
			}

			// translate method call into sql function call
			List<SqlExpression> sqlParams = GetFunctionParameters(mce, function);

			SqlStoredProcedureCall spc = new SqlStoredProcedureCall(function, null, sqlParams, mce);

			Type returnType = mce.Method.ReturnType;
			if(returnType.IsGenericType &&
				(returnType.GetGenericTypeDefinition() == typeof(IEnumerable<>) ||
				returnType.GetGenericTypeDefinition() == typeof(ISingleResult<>)))
			{

				// Since this is a single rowset returning sproc, we use the one
				// and only root metatype.
				MetaType rowType = function.ResultRowTypes[0].InheritanceRoot;

				SqlUserRow rowExp = new SqlUserRow(rowType, _typeProvider.GetApplicationType((int)ConverterSpecialTypes.Row), spc, mce);
				spc.Projection = _translator.BuildProjection(rowExp, rowType, _allowDeferred, null, mce);
			}
			else if(!(
				typeof(IMultipleResults).IsAssignableFrom(returnType)
				|| returnType == typeof(int)
				|| returnType == typeof(int?)
				))
			{
				throw Error.InvalidReturnFromSproc(returnType);
			}

			return spc;
		}
		internal override SqlStoredProcedureCall VisitStoredProcedureCall(SqlStoredProcedureCall spc)
		{
			List<SqlExpression> args = new List<SqlExpression>(spc.Arguments.Count);
			foreach(SqlExpression expr in spc.Arguments)
			{
				args.Add(this.VisitExpression(expr));
			}
			SqlExpression projection = this.VisitExpression(spc.Projection);
			SqlStoredProcedureCall n = new SqlStoredProcedureCall(spc.Function, projection, args, spc.SourceExpression);
			this.nodeMap[spc] = n;
			foreach(SqlUserColumn suc in spc.Columns)
			{
				n.Columns.Add((SqlUserColumn)this.Visit(suc));
			}
			return n;
		}
		internal override SqlStoredProcedureCall VisitStoredProcedureCall(SqlStoredProcedureCall spc)
		{
			_commandStringBuilder.Append("EXEC @RETURN_VALUE = ");
			this.WriteName(spc.Function.MappedName);
			_commandStringBuilder.Append(" ");

			int pc = spc.Function.Parameters.Count;
			Diagnostics.Debug.Assert(spc.Arguments.Count >= pc);

			for(int i = 0; i < pc; i++)
			{
				MetaParameter mp = spc.Function.Parameters[i];
				if(i > 0) _commandStringBuilder.Append(", ");
				this.WriteVariableName(mp.MappedName);
				_commandStringBuilder.Append(" = ");
				this.Visit(spc.Arguments[i]);
				if(mp.Parameter.IsOut || mp.Parameter.ParameterType.IsByRef)
					_commandStringBuilder.Append(" OUTPUT");
			}

			if(spc.Arguments.Count > pc)
			{
				if(pc > 0) _commandStringBuilder.Append(", ");
				this.WriteVariableName(spc.Function.ReturnParameter.MappedName);
				_commandStringBuilder.Append(" = ");
				this.Visit(spc.Arguments[pc]);
				_commandStringBuilder.Append(" OUTPUT");
			}

			return spc;
		}
		internal override SqlStoredProcedureCall VisitStoredProcedureCall(SqlStoredProcedureCall spc)
		{
			this.VisitUserQuery(spc);

			for(int i = 0, n = spc.Function.Parameters.Count; i < n; i++)
			{
				MetaParameter mp = spc.Function.Parameters[i];
				SqlParameter arg = spc.Arguments[i] as SqlParameter;
				if(arg != null)
				{
					arg.Direction = this.GetParameterDirection(mp);
					if(arg.Direction == ParameterDirection.InputOutput ||
					   arg.Direction == ParameterDirection.Output)
					{
						// Text, NText and Image parameters cannot be used as output parameters
						// so we retype them if necessary.
						RetypeOutParameter(arg);
					}
				}
			}

			// add default return value 
			SqlParameter p = new SqlParameter(typeof(int?), this.parameterizer.TypeProvider.From(typeof(int)), "@RETURN_VALUE", spc.SourceExpression);
			p.Direction = Data.ParameterDirection.Output;
			this.currentParams.Add(new SqlParameterInfo(p));

			return spc;
		}