在实现表值参数时,生成供该参数使用的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";

这段代码似乎确实有效。虽然重用SqlMetaData不会引起太多警钟,但在SqlDataRecord循环之外声明 foreach 对我来说令人难以置信:

可变对象被修改,然后反复产生。

例如,在LinqPad中调用var x = Rows(new[] { 100, 200}.ToList()).ToList().Dump()会吐出200,200。这种方法似乎依赖于实现细节(行是单独处理的),但是我看不到任何有保证的文档。

是否有一些缓解因素可以使此方法安全?

最佳答案



正如user1249190所指出的,在https://docs.microsoft.com/en-us/dotnet/api/microsoft.sqlserver.server.sqldatarecord#remarks的备注部分中明确建议重用SQLDataRecord:



显然,此建议不适用于跨线程使用:文档还明确警告:“不保证任何实例成员都是线程安全的”。

关于c# - 重用SqlDataRecord是否安全?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37007018/

10-11 16:05