我正在尝试做的是在使用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,获取异常,抓住它然后尝试下一个结果,但这只是为了该死的不干净(和错误)。
答案 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")