Subsonic SQL Server中是否缺少对亚音速3.0输出参数/默认参数的支持?
我有一个存储过程:Subsonic SQL Server中是否缺少对亚音速3.0输出参数/默认参数的支持?,subsonic,subsonic3,subsonic-active-record,Subsonic,Subsonic3,Subsonic Active Record,我有一个存储过程: CREATE PROCEDURE MyProc ( @P1 uniqueidentifier, @P2 int = NULL output, @P3 int = NULL output ) C端的签名应该是Guid P1,int?P2,int?我想是P3。但它不是,它只是Guid,int,int。此外,输出参数不是作为输出参数创建的,它们只是直接的AddParameterP2,arg,DbType.Int32。这是为了工作吗?好吧,看起来本机T4模板处理得不太好。事实上,我
CREATE PROCEDURE MyProc ( @P1 uniqueidentifier, @P2 int = NULL output, @P3 int = NULL output )
C端的签名应该是Guid P1,int?P2,int?我想是P3。但它不是,它只是Guid,int,int。此外,输出参数不是作为输出参数创建的,它们只是直接的AddParameterP2,arg,DbType.Int32。这是为了工作吗?好吧,看起来本机T4模板处理得不太好。事实上,我们在VS2003的时候建造了一些更复杂的东西,所以我将其更新为亚音速。其思想是,每个存储的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.t中的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;
}
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");
}
}
}
然后是Settings.ttinclude中的类声明
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;
}
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");
}
}
}
谢谢@Max,我对没有为params获取DbType感到沮丧。