你有一个“强”类型的DataReader结果集吗?

时间:2014-12-21 11:56:26

标签: c# sql sqldatareader

我正在尝试做的是在使用datareader.GetOrdinal()时从IndexOutOfRangeException安全保护我的C#数据检索代码。如果我的程序没有改变并且它们只返回一个结果集,这没有问题。但是如果它们返回多个结果集,那么我需要使用.NextResult()迭代结果集。那没问题。

但是,如果有人将程序更改为另一个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,获取异常,抓住它然后尝试下一个结果,但这只是为了该死的不干净(和错误)。

2 个答案:

答案 0 :(得分:0)

使用OR / M是一种很好的做法,但当然也有例外。例如,您可能被迫查询不支持存储过程的SQL服务器(SQL Server Compact等)。要提高性能,您可以选择使用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和Entity Framework的安全性。

答案 1 :(得分:0)

假设每个结果集都有一个唯一命名的第一列,对于伪代码示例中的以下行:

if(reader.Result != "The result with someColumnName")

您可以使用SqlDataReader.GetName函数检查第一列的名称。例如:

if(reader.GetName(0) != "ExpectedColumnName")