Bri*_*ian 9 c# sql-server table-valued-parameters
在实现表值参数时,生成IEnumerable<SqlDataRecord>参数使用的最常见方法之一是这样的代码(例如,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";
Run Code Online (Sandbox Code Playgroud)
这段代码似乎确实有效.虽然重用SqlMetaData并没有引发太多的警钟,但声明SqlDataRecord外面的foreach循环让我感到非常怀疑:
修改可变对象,然后重复生成.
作为一个关于这个问题的一个例子,var x = Rows(new[] { 100, 200}.ToList()).ToList().Dump()在LinqPad中调用吐出来200,200.这种方法似乎依赖于实现细节(行是单独处理的),但我没有看到任何承诺这样做的文档.
是否有一些减轻因素使这种方法安全?
这种方法似乎依赖于实现细节(行是单独处理的),但我没有看到任何承诺这一点的文档。
是否有一些缓解因素可以使这种方法安全?
正如 user1249190 指出的那样,在https://learn.microsoft.com/en-us/dotnet/api/microsoft.sqlserver.server.sqldatarecord#remarks的备注部分中明确建议重用 SQLDataRecord :
此类与 SqlPipe 一起使用,将结果集从托管代码存储过程发送到客户端。在编写公共语言运行时 (CLR) 应用程序时,您应该重用现有的 SqlDataRecord 对象,而不是每次都创建新对象。创建许多新的 SqlDataRecord 对象可能会严重耗尽内存并对性能产生不利影响。
显然,此建议不适用于跨线程的使用:文档还明确警告“不保证任何实例成员都是线程安全的”。
| 归档时间: |
|
| 查看次数: |
1068 次 |
| 最近记录: |