2010-01-07 110 views
2

我有一个存储过程:Subsonic 3.0在SQL Server中缺少输出参数/默认参数支持?

CREATE PROCEDURE MyProc (@P1 uniqueidentifier, @P2 int = NULL output, @P3 int = NULL output) 

在C#端的签名应该是(?的Guid P1,P2 INT,INT P3),我觉得。但事实并非如此(Guid,int,int)。此外,输出参数不会创建为输出参数,它们只是直的“AddParameter(P2,arg,DbType.Int32)”。这是否意味着工作?

回答

2

好吧,它看起来并不像原生T4模板处理得这么好。在VS2003的日子里,我们实际上已经构建了一些更复杂的东西,所以我已经将它更新为Subsonic。这个想法是,每个存储的proc获取一个类而不是一个函数,并具有可为空的参数属性。我已经修改了几个模板,我敢肯定,我在这里失去了一些东西,这是不是“生产质量”,但这里的StoredProcedures.tt

<#@ template language="C#v3.5" debug="False" hostspecific="True" #> 
<#@ output extension=".cs" #> 
<#@ include file="SQLServer.ttinclude" #> 
<# 
    var sps = GetSPs(); 
    if(sps.Count>0){ 
#> 
using System; 
using SubSonic; 
using SubSonic.Schema; 
using SubSonic.DataProviders; 
using System.Data; 

namespace <#=Namespace#>{ 
    public partial class <#=DatabaseName#>DB{ 

<# foreach(var sp in sps){#> 
     public class <#=sp.CleanName#> : StoredProcedure 
     { 
      public <#=sp.CleanName#>(<#=DatabaseName#>DB database, <#=sp.ArgList#>) : base("<#=sp.Name#>",database.Provider) 
      { 
<#  foreach(var par in sp.Parameters){ 
      if (par.IsOutput) { #> 
       Command.AddOutputParameter("<#=par.Name#>",DbType.<#=par.DbType#>); 
<# 
      } 
      else 
      { 
#> 
       Command.AddParameter("<#=par.Name#>",<#=par.CleanName#>,DbType.<#=par.DbType#>); 
<#  
      } 
     }#> 
      } 

<# foreach (var par in sp.Parameters) { #> 
      public <#= par.SysType #><#= par.ShouldBeNullable ? "?" : "" #> <#= par.CleanName #> 
      { 
       get 
       { 
        object val = Command.Parameters.GetParameter("<#= par.Name #>").ParameterValue; 
        return val == DBNull.Value ? default(<#= par.SysType #><#= par.ShouldBeNullable ? "?" : "" #>) : (<#= par.SysType #><#= par.ShouldBeNullable ? "?" : "" #>)val; 
       } 
       set    
       { 
<#   if (par.ShouldBeNullable) { #> 
        object val = value.HasValue ? (object)value : (object)DBNull.Value; 
        Command.Parameters.GetParameter("<#= par.Name #>").ParameterValue = val; 
<#   } #> 
       } 
      } 
<# } #> 
     } 


<# } #> 
    } 

} 
<# }#> 

下面是从SQLServer.ttinclude

的GetSPParams功能
List<SPParam> GetSPParams(string spName){ 
    var result=new List<SPParam>(); 
    string[] restrictions = new string[4] { DatabaseName, null, spName, null }; 
    using(SqlConnection conn=new SqlConnection(ConnectionString)){ 
     conn.Open(); 
     var sprocs=conn.GetSchema("ProcedureParameters", restrictions); 
     conn.Close(); 
     foreach(DataRow row in sprocs.Select("", "ORDINAL_POSITION")){ 
      SPParam p=new SPParam(); 
      p.SysType=GetSysType(row["DATA_TYPE"].ToString()); 
      p.DbType=GetDbType(row["DATA_TYPE"].ToString()).ToString(); 
      p.Name=row["PARAMETER_NAME"].ToString().Replace("@",""); 
      p.IsOutput=(row["PARAMETER_MODE"].ToString() == "INOUT"); 
      p.CleanName=CleanUp(p.Name); 
      result.Add(p); 
     } 


    } 
    return result; 
} 

然后从Settings.ttinclude

public class SP{ 
    public string Name; 
    public string CleanName; 
    public string ClassName; 
    public List<SPParam> Parameters; 
    public SP(){ 
     Parameters=new List<SPParam>(); 
    }   
    public string ArgList{ 
     get{ 
      StringBuilder sb=new StringBuilder(); 
      foreach(var par in Parameters){ 
        if (par.ShouldBeNullable) { continue; } 
       if(sb.Length != 0) 
       { 
        sb.Append(", "); 
       } 
       sb.AppendFormat("{0}{1} {2}", par.SysType, par.ShouldBeNullable ? "?" : "", par.CleanName); 
      } 
      return sb.ToString(); 
     } 
    } 
} 
public class SPParam{ 
    public string Name; 
    public string CleanName; 
    public string SysType; 
    public string DbType; 
    public bool IsOutput; 
    public bool ShouldBeNullable 
    { 
    get 
    { 
      return IsOutput && (SysType == "int" || SysType == "bool" || SysType == "double" || SysType == "long" || SysType == "short" || SysType == "decimal"); 
    } 
    } 
} 
+0

感谢@Max类的声明,我没有取得'DbType'为PARAMS受挫。 – TheVillageIdiot 2010-02-02 22:29:32