实现表值参数时,生成表值参数的最常见方法之一IEnumerable<SqlDataRecord>
参数使用的代码如下(例如,https://stackoverflow.com/a/10779567/18192 https://stackoverflow.com/a/10779567/18192 ):
public static IEnumerable<SqlDataRecord> Rows(List<int> simpletable)
{
var smd = new []{ new SqlMetaData("id", SqlDbType.Int)};
var sqlRow = new SqlDataRecord(smd);
foreach (int i in simpletable)
{
sqlRow.SetInt32(0, i);
yield return sqlRow;
}
}
//...
var param = sqlCmd.Parameters.AddWithValue("@retailerIDs", Rows(mydata));
param.SqlDbType = SqlDbType.Structured;
param.TypeName = "myTypeName";
这段代码似乎确实有效。重复使用时SqlMetaData
不会引起太多警钟,宣告SqlDataRecord https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.server.sqldatarecord.aspx之外的foreach
循环对我来说非常可疑:
可变对象被修改然后重复生成。
作为一个例子来说明为什么这是令人担忧的,调用var x = Rows(new[] { 100, 200}.ToList()).ToList().Dump()
在 LinqPad 中吐出200,200
。这种方法似乎依赖于实现细节(行是单独处理的),但我没有看到任何承诺这一点的文档。
是否有一些缓解因素可以使这种方法安全?
这种方法似乎依赖于实现细节(行是
单独处理),但我没有看到任何文档
承诺这一点。
是否有一些缓解因素可以使这种方法安全?
正如 user1249190 指出的,在备注部分明确建议重用 SQLDataRecordhttps://learn.microsoft.com/en-us/dotnet/api/microsoft.sqlserver.server.sqldatarecord#remarks https://learn.microsoft.com/en-us/dotnet/api/microsoft.sqlserver.server.sqldatarecord#remarks :
该类与 SqlPipe 一起使用,将结果集发送到
来自托管代码存储过程的客户端。写常见的时候
语言运行时 (CLR) 应用程序,您应该重用现有的
SqlDataRecord 对象,而不是每次都创建新对象。
创建许多新的 SqlDataRecord 对象可能会严重耗尽内存
并对性能产生不利影响。
显然,此建议不适用于跨线程的使用:文档还明确警告“不保证任何实例成员都是线程安全的”。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)