我有一个存储过程:
CREATE PROCEDURE MyProc ( @P1 uniqueidentifier, @P2 int = NULL output, @P3 int = NULL output )
C#侧的签名应该是(Guid P1,int?P2,int?P3)我想。但它不是,它只是(Guid,int,int)。此外,输出参数不是作为输出参数创建的,它们只是直接的“AddParameter(P2,arg,DbType.Int32)”。这意味着什么?
答案 0 :(得分:2)
嗯,它看起来不像原生T4模板那么好。在VS2003时代,我们实际上已经构建了一些更复杂的东西,所以我为Subsonic更新了它。这个想法是每个存储过程获得一个类而不是一个函数,并具有参数的可空属性。我修改了几个模板,我确定我在这里遗漏了一些东西,这不是“生产质量”,但这里是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");
}
}
}