【发布时间】:2020-12-15 20:17:05
【问题描述】:
我正在尝试从我的 .NET Core Web API 上的存储过程中读取值。
这是得到的响应:
System.InvalidOperationException: Invalid attempt to call FieldCount when reader is closed.
at Microsoft.Data.SqlClient.SqlDataReader.get_FieldCount()
at System.Data.Common.DbEnumerator.BuildSchemaInfo()
at System.Data.Common.DbEnumerator.MoveNext()
at System.Text.Json.JsonSerializer.HandleEnumerable(JsonClassInfo elementClassInfo, JsonSerializerOptions options, Utf8JsonWriter writer, WriteStack& state)
at System.Text.Json.JsonSerializer.Write(Utf8JsonWriter writer, Int32 originalWriterDepth, Int32 flushThreshold, JsonSerializerOptions options, WriteStack& state)
at System.Text.Json.JsonSerializer.WriteAsyncCore(Stream utf8Json, Object value, Type inputType, JsonSerializerOptions options, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|29_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
这是我的代码:
try
{
using (SqlConnection con = new SqlConnection(myConnString))
{
using (SqlCommand cmd = new SqlCommand("GetUsers", con)) // Simple proc which returning all 'child' users
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@parentUserId", SqlDbType.UniqueIdentifier).Value = parentUserId;
// open connection to database
con.Open();
//set the SqlCommand type to stored procedure and execute
cmd.CommandType = CommandType.StoredProcedure;
SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
message.Data = reader;
}
}
return message;
}
catch (Exception ex)
{
message.IsValid = false;
}
当我对此进行调试时,我意识到数据存在于结果中,但它嵌套在另一个对象中,就像它在此处的图像上显示的那样:
【问题讨论】:
-
当代码从包含连接的 using 块中退出时,连接及其关联的读取器都将被关闭。
-
您需要保持连接和阅读器处于活动状态(即未处置),直到您完成阅读阅读器。 DataReaders 和 using 语句并不总是很好的匹配。
-
@Steve 感谢您的精彩解释!我怎么能避免这种情况,你能帮我取悦史蒂夫吗?谢谢!
-
通常 DataReader 不会从创建它的方法中传递出去。我通常避免使用它(数据读取器)并用像 Dapper 这样的良好 ORM 替换它,它会自动将我的查询转换为我的模型中定义的对象列表。我认为这应该是解决您问题的方法
标签: c# sql-server stored-procedures .net-core sqldatareader