gpt4 book ai didi

c# - SqlDataReader 的 Connection 属性为 Null

转载 作者:太空狗 更新时间:2023-10-29 23:36:49 24 4
gpt4 key购买 nike

我遇到了一个奇怪的问题,我能够从对存储过程的调用中返回结果,但代码会追溯失败。

public IEnumerable<T> ExecuteStoredProcedure<T>(string storedProcedureName, IDataMapper<T> mapper, IDictionary<string, object> parameters)
{
using (var connection = new SqlConnection(connectionString))
{
using (var cmd = new SqlCommand(storedProcedureName, connection))
{
cmd.CommandType = CommandType.StoredProcedure;
foreach (var key in parameters.Keys)
{
cmd.Parameters.AddWithValue(key, parameters[key]);
}
connection.Open();
SqlDataReader reader = cmd.ExecuteReader();
//return MapRecordsToDTOs(reader, mapper);

//let's test:
IEnumerable<T> result = MapRecordsToDTOs(reader, mapper);
var x = (new List<T>(result)).Count;
System.Diagnostics.Debug.WriteLine(x);
return result;
}
}
}


private static IEnumerable<T> MapRecordsToDTOs<T>(SqlDataReader reader, IDataMapper<T> mapper)
{
if (reader.HasRows)
{
while (reader.Read())
{
System.Diagnostics.Debug.WriteLine(reader["Id"]); //what's going on...
yield return mapper.MapToDto((IDataRecord)reader);
}
}
}

调用此代码表明变量 x 始终代表我希望从调用我的存储过程中看到的行数。

此外,我的调试输出显示了我希望看到的 ID 值。

但是,返回这些结果后,我收到错误 An exception of type 'System.InvalidOperationException' occurred in System.Data.dll but was not handled in user code 从行 if (reader.HasRows)(即已经执行)。我调用此请求的浏览器显示 HTTP Error 502.3 - Bad Gateway

Screenshot of Error

Screenshot of HasRows Behaviour

我怀疑原因是系统正在计算用于调试的 IDX 值,以及它如何返回真实的用户输出。因此,它执行惰性操作以在必须返回它们时获取 IEnumerable 值;只有在这一点上,using 语句才导致调用 dispose 方法,因此读取器的连接为空(这是我在检查 reader 变量的属性时看到的同时调试)。

有没有人见过这样的行为/这是一个错误吗?还是我只是错过了一些明显的东西?


附加代码:

public interface IDataMapper<T>
{
T MapToDto(IDataRecord record);
}

public class CurrencyMapper: IDataMapper<CurrencyDTO>
{
const string FieldNameCode = "Code";
const string FieldNameId = "Id";
const string FieldNameName = "Name";
const string FieldNameNum = "Num";
const string FieldNameE = "E";
const string FieldNameSymbol = "Symbol";

public CurrencyMapper() { }

public CurrencyDTO MapToDto(IDataRecord record)
{
var code = record[FieldNameCode] as string;
var id = record[FieldNameId] as Guid?;
var name = record[FieldNameName] as string;
var num = record[FieldNameNum] as string;
var e = record[FieldNameE] as int?;
var symbol = record[FieldNameSymbol] as char?;
return new CurrencyDTO(id, code, num, e, name, symbol);
}
}

public class CurrencyRepository
{

const string SPReadAll = "usp_CRUD_Currency_ReadAll";

readonly SqlDatabase db;
public CurrencyRepository()
{
db = new SqlDatabase(); //stick to SQL only for the moment for simplicity
}
public IEnumerable<CurrencyDTO> GetCurrencyCodes()
{
var mapper = new CurrencyMapper();
return db.ExecuteStoredProcedure(SPReadAll, mapper);
}
}

public class CurrencyDTO
{

readonly Guid? id;
readonly string code;
readonly string num;
readonly int? e;
readonly string name;
readonly char? symbol;

public CurrencyDTO(Guid? id,string code,string num,int? e,string name, char? symbol)
{
this.id = id;
this.code = code;
this.num = num;
this.e = e;
this.name = name;
this.symbol = symbol;
}

public Guid? Id { get { return id; } }
public string Code { get { return code; } }
public string Num { get { return num; } }
public int? E { get { return e; } }
public string Name { get { return name; } }
public char? Symbol { get { return symbol; } }
}

最佳答案

我已经临时实现了解决此问题的解决方法。

这个有效:

private static IEnumerable<T> MapRecordsToDTOs<T>(SqlDataReader reader, IDataMapper<T> mapper)
{
var list = new List<T>(); //use a list to force eager evaluation
if (reader.HasRows)
{
while (reader.Read())
{
list.Add(mapper.MapToDto((IDataRecord)reader));
}
}
return list.ToArray();
}

相对于原来的:

private static IEnumerable<T> MapRecordsToDTOs<T>(SqlDataReader reader, IDataMapper<T> mapper)
{
if (reader.HasRows)
{
while (reader.Read())
{
yield return mapper.MapToDto((IDataRecord)reader);
}
}
}

不同之处在于我移动了受迭代器影响的代码,使其只迭代列表中的结果;并且不依赖编译器明智地理解与 IDisposable 对象相关的要求。

据我了解,编译器应该能够为我处理此问题(已在此处确认:https://stackoverflow.com/a/13504789/361842),因此我怀疑这是编译器中的错误。

此处报告:https://connect.microsoft.com/VisualStudio/feedback/details/3113138

额外的演示代码在这里: https://gist.github.com/JohnLBevan/a910d886df577e442e2f5a9c2dd41293/

关于c# - SqlDataReader 的 Connection 属性为 Null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40792854/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com