글쎄, 네이티브 T4 템플릿이 이걸 잘 처리하는 것처럼 보이지 않습니다. 우리는 실제로 VS2003 일 동안 좀 더 복잡한 것을 만들었으므로 Subsonic 용으로 업데이트했습니다. 아이디어는 각 저장된 proc이 함수 대신 클래스를 가져오고 매개 변수에 대해 nullable 속성을 가졌다는 것입니다. 난 내가 여기서 뭔가를 누락 확신이없는 "생산 품질"입니다, 몇 가지 템플릿을 수정했지만, 여기 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");
}
}
}
감사 @Max에서 클래스 선언은, 나는 PARAMS에 대한'DbType'을받지에 의해 좌절되었다. – TheVillageIdiot