private CodeMemberMethod GenerateProcedureMethod( Signature s, ProcedureOptions po, bool Transacted) { // Create the method var m = new CodeMemberMethod { Name = s.Name, Attributes = (MemberAttributes.Public | MemberAttributes.Static) }; // Figure the actual return type var rt = po.ReturnType; if (ProcedureReturnType.NotSpecified == po.ReturnType) { rt = ProcedureReturnType.Auto; } if (ProcedureReturnType.Auto == po.ReturnType) { if (po.TypedDataSet != null) { rt = ProcedureReturnType.TypedDataSet; } else if (s.ResultSets != null && s.ResultSets.Count > 0) { rt = Options.AutoReturnType; } else { rt = ProcedureReturnType.None; } } // Set return type switch (rt) { case ProcedureReturnType.TypedDataSet: if (string.IsNullOrEmpty(po.TypedDataSet)) { throw new Exception("The return type was specified as TypedDataSet, but no TypedDataSet name was specified."); } m.ReturnType = new CodeTypeReference(po.TypedDataSet); break; case ProcedureReturnType.None: m.ReturnType = null; break; default: Type t; switch (rt) { case ProcedureReturnType.DataSet: t = typeof(DataSet); break; case ProcedureReturnType.SqlDataReader: t = typeof(SqlDataReader); break; default: throw new Exception("Unknown Procedure Return Type."); } m.ReturnType = new CodeTypeReference(t); break; } // Set parameters if (Transacted) { m.Parameters.Add( new CodeParameterDeclarationExpression( typeof(SqlTransaction), "trs")); } foreach (Parameter p in s.Parameters) { var pde = new CodeParameterDeclarationExpression( po.NullableParams.Contains(p.Name) ? p.SqlType : p.FrameworkType, FormatIdentifier(Options, p.FrameworkName)); if (p.Type == "output") { pde.Direction = FieldDirection.Out; } m.Parameters.Add(pde); } // if this signature generated an error, place a // #warning here if (s.Exception != null && Options.GenerateWarnings) { // this will generate a compile warning in c#, as it should, // but will cause a syntax error in VB. Too bad vb doesnt have any // type of precompiler warning syntax. var errmsg = s.Exception.Message.Replace('\r', ' ').Replace('\n', ' '); if (errmsg.Length > 200) { errmsg = errmsg.Substring(0, 200); } m.Statements.Add( new CodeSnippetStatement( String.Format("#warning {0}: \"{1}\"", s.Name, errmsg) )); } // Add any userdefined code to the beginning of the method if (Options.SnippetPre != String.Empty) { m.Statements.Add(new CodeSnippetStatement(Options.SnippetPre)); } // Create SqlParameter expressions var l = new List <CodeExpression>(); var outputs = new CodeStatementCollection(); var assigns = new CodeStatementCollection(); for (var i = 0; i < s.Parameters.Count; i++) { var p = (Parameter)s.Parameters[i]; l.Add( new CodeObjectCreateExpression( typeof(SqlParameter), new[] { new CodePrimitiveExpression(p.Name), (p.Type == "input") ? new CodeArgumentReferenceExpression(FormatIdentifier(Options, p.FrameworkName)) : ((CodeExpression) new CodeFieldReferenceExpression( new CodeTypeReferenceExpression(typeof(SqlDbType)), p.SqlDbType.ToString()) ) } ) ); if ("output" == p.Type) { // add statments to set the direction to output outputs.Add( new CodeAssignStatement( new CodePropertyReferenceExpression( new CodeIndexerExpression( new CodeVariableReferenceExpression("parms"), new CodePrimitiveExpression(i) ), "Direction" ), new CodeFieldReferenceExpression( new CodeTypeReferenceExpression(typeof(ParameterDirection)), "Output" ) ) ); // character and binary types need the output size set var t = p.SqlDbType; if (t == SqlDbType.Char || t == SqlDbType.VarChar || t == SqlDbType.NChar || t == SqlDbType.NVarChar || t == SqlDbType.Binary || t == SqlDbType.VarBinary) { outputs.Add( new CodeAssignStatement( new CodePropertyReferenceExpression( new CodeIndexerExpression( new CodeVariableReferenceExpression("parms"), new CodePrimitiveExpression(i) ), "Size" ), new CodePrimitiveExpression(p.Size) ) ); } // we need to pass the value back to the out param // is this a 'nullable' parameter? if (po.NullableParams.Contains(p.Name)) { // [argument] = ReadSqlABC(parms[i]); string method; var tt = p.SqlType; if (tt == typeof(SqlDateTime)) { method = "ReadSqlDateTime"; } else if (tt == typeof(SqlInt32)) { method = "ReadSqlInt32"; } else if (tt == typeof(SqlMoney)) { method = "ReadSqlMoney"; } else if (tt == typeof(SqlString)) { method = "ReadSqlString"; } else if (tt == typeof(SqlGuid)) { method = "ReadSqlGuid"; } else { throw new Exception("Cannot read nullable sql type: " + tt); } assigns.Add( new CodeAssignStatement( new CodeArgumentReferenceExpression(FormatIdentifier(Options, p.FrameworkName)), new CodeMethodInvokeExpression( new CodeTypeReferenceExpression(Options.ClassName), method, new CodeIndexerExpression( new CodeVariableReferenceExpression("parms"), new CodePrimitiveExpression(i) ) ) ) ); } else { // [argument] = (type)parms[i].Value; assigns.Add( new CodeAssignStatement( new CodeArgumentReferenceExpression(FormatIdentifier(Options, p.FrameworkName)), new CodeCastExpression( p.FrameworkType, new CodePropertyReferenceExpression( new CodeIndexerExpression( new CodeVariableReferenceExpression("parms"), new CodePrimitiveExpression(i) ), "Value" ) ) ) ); } } } // Create parms array m.Statements.Add( new CodeVariableDeclarationStatement( new CodeTypeReference( new CodeTypeReference(typeof(SqlParameter)), 1), "parms", new CodeArrayCreateExpression( typeof(SqlParameter), l.ToArray()) ) ); // Add any parms[n].Direction = ... statements m.Statements.AddRange(outputs); // Create the SqlHelper parameters.. always the same var parms = new CodeExpression[] { new CodePrimitiveExpression(s.DatabaseName), new CodeVariableReferenceExpression("parms") }; if (Transacted) { parms = new[] { new CodeArgumentReferenceExpression("trs"), parms[0], parms[1] }; } // Run the sproc switch (rt) { case ProcedureReturnType.TypedDataSet: m.Statements.Add( new CodeVariableDeclarationStatement( new CodeTypeReference(po.TypedDataSet), "ds", new CodeObjectCreateExpression( new CodeTypeReference(po.TypedDataSet)) ) ); m.Statements.Add( new CodeMethodInvokeExpression( null, "FillDataSet", Transacted ? new[] { parms[0], parms[1], parms[2], new CodeVariableReferenceExpression("ds") } : new[] { parms[0], parms[1], new CodeVariableReferenceExpression("ds") } ) ); m.Statements.Add( new CodeMethodReturnStatement( new CodeVariableReferenceExpression("ds") ) ); break; case ProcedureReturnType.DataSet: m.Statements.Add( new CodeMethodReturnStatement( new CodeMethodInvokeExpression( null, "ExecuteDataSet", parms ) ) ); break; case ProcedureReturnType.SqlDataReader: m.Statements.Add( new CodeMethodReturnStatement( new CodeMethodInvokeExpression( null, "ExecuteDataReader", parms ) ) ); break; case ProcedureReturnType.None: m.Statements.Add( new CodeMethodInvokeExpression( null, "ExecuteNonQuery", parms ) ); m.Statements.AddRange(assigns); break; default: throw new Exception("Unknown Procedure Return Type."); } // Add any userdefined code to the end of the method if (Options.SnippetPost != String.Empty) { m.Statements.Add(new CodeSnippetStatement(Options.SnippetPost)); } return(m); }
private CodeMemberMethod GenerateProcedureMethod( Signature s, ProcedureOptions po, bool Transacted) { // Create the method var m = new CodeMemberMethod { Name = s.Name, Attributes = (MemberAttributes.Public | MemberAttributes.Static) }; // Figure the actual return type var rt = po.ReturnType; if (ProcedureReturnType.NotSpecified == po.ReturnType) { rt = ProcedureReturnType.Auto; } if (ProcedureReturnType.Auto == po.ReturnType) { if (po.TypedDataSet != null) { rt = ProcedureReturnType.TypedDataSet; } else if (s.ResultSets != null && s.ResultSets.Count > 0) { rt = Options.AutoReturnType; } else { rt = ProcedureReturnType.None; } } // Set return type switch (rt) { case ProcedureReturnType.TypedDataSet: if (string.IsNullOrEmpty(po.TypedDataSet)) { throw new Exception("The return type was specified as TypedDataSet, but no TypedDataSet name was specified."); } m.ReturnType = new CodeTypeReference(po.TypedDataSet); break; case ProcedureReturnType.None: m.ReturnType = null; break; default: Type t; switch (rt) { case ProcedureReturnType.DataSet: t = typeof(DataSet); break; case ProcedureReturnType.SqlDataReader: t = typeof(SqlDataReader); break; default: throw new Exception("Unknown Procedure Return Type."); } m.ReturnType = new CodeTypeReference(t); break; } // Set parameters if (Transacted) { m.Parameters.Add( new CodeParameterDeclarationExpression( typeof(SqlTransaction), "trs")); } foreach (Parameter p in s.Parameters) { var pde = new CodeParameterDeclarationExpression( po.NullableParams.Contains(p.Name) ? p.SqlType : p.FrameworkType, FormatIdentifier(Options, p.FrameworkName)); if (p.Type == "output") { pde.Direction = FieldDirection.Out; } m.Parameters.Add(pde); } // if this signature generated an error, place a // #warning here if (s.Exception != null && Options.GenerateWarnings) { // this will generate a compile warning in c#, as it should, // but will cause a syntax error in VB. Too bad vb doesnt have any // type of precompiler warning syntax. var errmsg = s.Exception.Message.Replace('\r', ' ').Replace('\n', ' '); if (errmsg.Length > 200) { errmsg = errmsg.Substring(0, 200); } m.Statements.Add( new CodeSnippetStatement( String.Format("#warning {0}: \"{1}\"", s.Name, errmsg) )); } // Add any userdefined code to the beginning of the method if (Options.SnippetPre != String.Empty) { m.Statements.Add(new CodeSnippetStatement(Options.SnippetPre)); } // Create SqlParameter expressions var l = new List<CodeExpression>(); var outputs = new CodeStatementCollection(); var assigns = new CodeStatementCollection(); for (var i = 0; i < s.Parameters.Count; i++) { var p = (Parameter)s.Parameters[i]; l.Add( new CodeObjectCreateExpression( typeof(SqlParameter), new[] { new CodePrimitiveExpression(p.Name), (p.Type == "input") ? new CodeArgumentReferenceExpression(FormatIdentifier(Options, p.FrameworkName)) : ((CodeExpression) new CodeFieldReferenceExpression( new CodeTypeReferenceExpression(typeof(SqlDbType)), p.SqlDbType.ToString()) ) } ) ); if ("output" == p.Type) { // add statments to set the direction to output outputs.Add( new CodeAssignStatement( new CodePropertyReferenceExpression( new CodeIndexerExpression( new CodeVariableReferenceExpression("parms"), new CodePrimitiveExpression(i) ), "Direction" ), new CodeFieldReferenceExpression( new CodeTypeReferenceExpression(typeof(ParameterDirection)), "Output" ) ) ); // character and binary types need the output size set var t = p.SqlDbType; if (t == SqlDbType.Char || t == SqlDbType.VarChar || t == SqlDbType.NChar || t == SqlDbType.NVarChar || t == SqlDbType.Binary || t == SqlDbType.VarBinary) { outputs.Add( new CodeAssignStatement( new CodePropertyReferenceExpression( new CodeIndexerExpression( new CodeVariableReferenceExpression("parms"), new CodePrimitiveExpression(i) ), "Size" ), new CodePrimitiveExpression(p.Size) ) ); } // we need to pass the value back to the out param // is this a 'nullable' parameter? if (po.NullableParams.Contains(p.Name)) { // [argument] = ReadSqlABC(parms[i]); string method; var tt = p.SqlType; if (tt == typeof(SqlDateTime)) { method = "ReadSqlDateTime"; } else if (tt == typeof(SqlInt32)) { method = "ReadSqlInt32"; } else if (tt == typeof(SqlMoney)) { method = "ReadSqlMoney"; } else if (tt == typeof(SqlString)) { method = "ReadSqlString"; } else if (tt == typeof(SqlGuid)) { method = "ReadSqlGuid"; } else { throw new Exception("Cannot read nullable sql type: " + tt); } assigns.Add( new CodeAssignStatement( new CodeArgumentReferenceExpression(FormatIdentifier(Options, p.FrameworkName)), new CodeMethodInvokeExpression( new CodeTypeReferenceExpression(Options.ClassName), method, new CodeIndexerExpression( new CodeVariableReferenceExpression("parms"), new CodePrimitiveExpression(i) ) ) ) ); } else { // [argument] = (type)parms[i].Value; assigns.Add( new CodeAssignStatement( new CodeArgumentReferenceExpression(FormatIdentifier(Options, p.FrameworkName)), new CodeCastExpression( p.FrameworkType, new CodePropertyReferenceExpression( new CodeIndexerExpression( new CodeVariableReferenceExpression("parms"), new CodePrimitiveExpression(i) ), "Value" ) ) ) ); } } } // Create parms array m.Statements.Add( new CodeVariableDeclarationStatement( new CodeTypeReference( new CodeTypeReference(typeof(SqlParameter)), 1), "parms", new CodeArrayCreateExpression( typeof(SqlParameter), l.ToArray()) ) ); // Add any parms[n].Direction = ... statements m.Statements.AddRange(outputs); // Create the SqlHelper parameters.. always the same var parms = new CodeExpression[] { new CodePrimitiveExpression(s.DatabaseName), new CodeVariableReferenceExpression("parms") }; if (Transacted) { parms = new[] { new CodeArgumentReferenceExpression("trs"), parms[0], parms[1] }; } // Run the sproc switch (rt) { case ProcedureReturnType.TypedDataSet: m.Statements.Add( new CodeVariableDeclarationStatement( new CodeTypeReference(po.TypedDataSet), "ds", new CodeObjectCreateExpression( new CodeTypeReference(po.TypedDataSet)) ) ); m.Statements.Add( new CodeMethodInvokeExpression( null, "FillDataSet", Transacted ? new[] { parms[0], parms[1], parms[2], new CodeVariableReferenceExpression("ds") } : new[] { parms[0], parms[1], new CodeVariableReferenceExpression("ds") } ) ); m.Statements.Add( new CodeMethodReturnStatement( new CodeVariableReferenceExpression("ds") ) ); break; case ProcedureReturnType.DataSet: m.Statements.Add( new CodeMethodReturnStatement( new CodeMethodInvokeExpression( null, "ExecuteDataSet", parms ) ) ); break; case ProcedureReturnType.SqlDataReader: m.Statements.Add( new CodeMethodReturnStatement( new CodeMethodInvokeExpression( null, "ExecuteDataReader", parms ) ) ); break; case ProcedureReturnType.None: m.Statements.Add( new CodeMethodInvokeExpression( null, "ExecuteNonQuery", parms ) ); m.Statements.AddRange(assigns); break; default: throw new Exception("Unknown Procedure Return Type."); } // Add any userdefined code to the end of the method if (Options.SnippetPost != String.Empty) { m.Statements.Add(new CodeSnippetStatement(Options.SnippetPost)); } return m; }