您能否有一个“强”类型的数据读取器结果集

本文关键字:数据 读取 结果 类型 有一个 | 更新日期: 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")