c#自动生成SQL“用户定义的表类型”
本文关键字:类型 定义 用户 自动生成 SQL | 更新日期: 2023-09-27 18:03:02
关于以用户定义的表类型作为参数的存储过程,我有一个问题。我知道我只需要在c#代码中创建一个DataTable,对应于SQL DB中用户定义的表类型。就像这里c#中如何传递用户定义表类型作为存储过程参数
然而,我想避免的是在代码中手动创建数据表,而是自动创建数据表。是否有可能通过查询从数据库中获取此信息?
如果这是不可能的,那么另一种可能性是获取用户定义的表类型的定义,然后使用它来自动生成DataTable。但问题是如何得到类型的定义呢?
任何人得到这个问题的任何解决方案,我发现的所有例子都是在代码中手动生成用户定义的数据类型为DataTable。
如果您知道表类型的名称,您应该能够执行以下SQL代码:
declare @a dbo.TT
select * from @a
(其中dbo.TT
为表类型的名称)
这将生成一个包含所有适当模式信息(列名和类型)的空结果集。如果你用DataAdapter
来填充DataTable
,你应该都设置好了。
试试这个(这只对向存储过程发送一列值的数据集有用)
public void AddSQLTableParm<T>(string parmName,
IEnumerable<T> values,
string typeName = "dbo.keyIds") // <== here put SQL Server UDT Type neame
{
var parm = new SqlParameter(parmName,
DbParamList.CreateDataTable(values))
{
SqlDbType = SqlDbType.Structured,
TypeName = typeName
};
Add(parmName, parm);
}
如果你想要一个多列数据集(SQL Server中的多列UDT),你将不得不扩展它,签名将变成:
对于三列数据集:
public void AddSQLTableParm<T1, T2, T3>(
string parmName, string typeName = "dbo.keyIds",
IEnumerable<T1> value1s,
IEnumerable<T1> value2s,
IEnumerable<T1> value3s)
{ .... }
dbParamList defined:
public class DbParamList : List<IDbDataParameter>
{
private DbParamList() {}
public static DbParamList Make(IEnumerable<SqlParameter> parms)
{
var prmLst = new DbParamList();
prmLst.AddRange(parms);
return prmLst;
}
public static DbParamList Make(params SqlParameter[] parms)
{
var prmLst = new DbParamList();
prmLst.AddRange(parms);
return prmLst;
}
public void AddSQLParm(string parmName, bool value)
{ Add(new SqlParameter(parmName, value ? "1" : "0")); }
public void AddSQLParm(string parmName, bool? value)
{
if (!value.HasValue)
{
throw new ArgumentNullException(
"Null value passed to AddSQLParm<>()");
}
Add(new SqlParameter(parmName, value.Value ? "1" : "0"));
}
public void AddSQLParm<T>(string parmName, T value)
{
var type = typeof(T);
if (type.IsEnum) Add(new SqlParameter(parmName,
Convert.ChangeType(value, Enum.GetUnderlyingType(type))));
else Add(new SqlParameter(parmName, value));
}
public void AddSQLParm<T>(string parmName, T? value,
bool ignoreNull = false) where T : struct
{
var type = typeof(T);
if (!value.HasValue)
{
if (ignoreNull) return;
throw new ArgumentNullException(
"Null value passed to AddSQLParm<>()");
}
// ---------------------------------------
if (type.IsEnum) Add(new SqlParameter(parmName,
Convert.ChangeType(value.Value, Enum.GetUnderlyingType(type))));
else Add(new SqlParameter(parmName, value.Value));
}
public void AddSQLTableParm<T>(string parmName, IEnumerable<T> values)
{
var parm = new SqlParameter(parmName, CreateDataTable(values))
{
SqlDbType = SqlDbType.Structured,
TypeName = "dbo.keyIds"
};
Add(parm);
}
internal static DataTable CreateDataTable<T>(IEnumerable<T> values)
{
var dt = new DataTable();
var props = typeof (T).GetProperties();
if (props.Length > 0)
{
foreach (var col in props)
dt.Columns.Add(col.Name, col.PropertyType);
foreach (var id in values)
{
var newRow = dt.NewRow();
foreach (var prop in id.GetType().GetProperties())
newRow[prop.Name] = prop.GetValue(id, null);
dt.Rows.Add(newRow);
}
}
else
{
dt.Columns.Add("ids");
foreach (var id in values) dt.Rows.Add(id);
}
return dt;
}
}