您能否有一个“强”类型的数据读取器结果集
本文关键字:数据 读取 结果 类型 有一个 | 更新日期: 2023-09-27 18:34:54
我试图做的是在使用datareader时保护我的C#数据检索代码免受IndexOutOfRangeException的影响。GetOrdinal((。如果我的过程没有更改并且它们只返回一个结果集,则没有问题。但是,如果他们返回多个结果集,那么我需要使用 .下一个结果((。这没问题。
但是,如果有人更改过程以具有另一个 select 语句,以便我的 C# 检索代码的顺序发生变化并且一切都会爆炸怎么办?
但问题是:我可以检查结果是否是我想要的结果吗?
下面是我喜欢做的伪代码。
using (SqlDataReader reader = cmd.ExecuteReader())
{
//The check I would like to be able to do
if(reader.Result != "The result with someColumnName")
{
//This is not the result Im looking for so I try the next one
reader.NextResult();
}
else //Get the result set I want.. If it blows up now it should..
{
if (reader.HasRows)
{
//Get all ordinals first. Faster than searching with index.
int someColumnNameOrdinal = reader.GetOrdinal("someColumnName");
while (reader.Read())
{
var someValue = reader.GetString(someColumnNameOrdinal );
}
}
}
}
我知道我可以尝试 GetOrdinal,获取异常,捕获它,然后尝试下一个结果,但这只是该死的不干净(和错误(。
使用 OR/M 是一种很好的做法,但当然也有例外。例如,您可能被迫查询不支持存储进程(SQL Server Compact 等(的 SQL Server。为了提高性能,您可以选择使用 SqlDataReader。为了确保字段名称始终正确(对应于实体类字段(,您可以使用以下做法 - 而不是硬编码字段名称,请使用此代码:
GetPropertyName((YourEntityClass c) => c.YourField)
其中 GetPropertyName 函数包含以下代码(使用泛型(:
public static string GetPropertyName<T, TReturn>(System.Linq.Expressions.Expression<Func<T, TReturn>> expression)
{
System.Linq.Expressions.MemberExpression body = (System.Linq.Expressions.MemberExpression)expression.Body;
return body.Member.Name;
}
YourEntityClass 是实体框架中表的类名,YourField 是此表中的字段名称。在这种情况下,您同时具有 SqlDataReader 的性能和实体框架的安全性。
假设每个结果集都有一个唯一命名的第一列,对于伪代码示例中的以下行:
if(reader.Result != "The result with someColumnName")
您可以使用 SqlDataReader.GetName 函数来检查第一列的名称。例如:
if(reader.GetName(0) != "ExpectedColumnName")