ADO.Net:检查IDataRecord上是否存在字段名称

ArB*_*rBR 7 c# ado.net

只有在IDataRecord中存在field_name时才有更好的方法从IDataRecord获取field_name值,目前我正在使用try {...} catch {...}块,但这是某种On Error接下来继续.一些替代品?

/// <summary>
/// Returns column value from IDataRecord only if field_name exists.
/// </summary>
public static Tresult ValueIfExists<Tresult>(this IDataRecord record, string field_name)
{
    try { return record.Value<Tresult>(record.GetOrdinal(field_name)); }
    catch { return default(Tresult); }
}

/// <summary>
/// Returns column value from IDataRecord accecing by index.
/// </summary>
public static Tresult Value<Tresult>(this IDataRecord record, int field_index)
{
    return record.IsDBNull(field_index) ? default(Tresult) :
              (Tresult)Convert.ChangeType(record[field_index], typeof(Tresult));
}
Run Code Online (Sandbox Code Playgroud)

我已经更改了我的ValueIfExists函数以反映您的想法,所以它看起来像这样:

public static Tresult ValueIfExists2<Tresult>(this IDataRecord record, string field_name)
{
    for (int index = 0; index < record.FieldCount; index++)
    {
        if (record.GetName(index).Equals(field_name, StringComparison.InvariantCulture))
        {
            return record.Value<Tresult>(record.GetOrdinal(field_name));
        }
    }
    return default(Tresult);
}
Run Code Online (Sandbox Code Playgroud)

Guf*_*ffa 16

你是对的,异常不应该用于正常的程序流程.

GetOrdinal方法适用于您知道所获得的字段以及缺少哪个字段是导致异常的错误的情况.

如果您不知道结果中包含哪些字段,则应避免使用该GetOrdinal方法.您可以将所有名称及其索引放入可用作该GetOrdinal方法替代的字典中:

public static Dictionary<string, int> GetAllNames(this IDataRecord record) {
  var result = new Dictionary<string, int>();
  for (int i = 0; i < record.FieldCount; i++) {
    result.Add(record.GetName(i), i);
  }
  return result;
}
Run Code Online (Sandbox Code Playgroud)

您可以使用该ContainsKey方法检查字典中是否存在名称,或者TryGetValue检查名称是否存在的方法,并在单个操作中获取它的索引.

GetOrdinal方法首先对名称进行大小写检测,如果失败,则进行案例本能搜索.这不是字典提供的,所以如果你想要那个确切的行为,你宁愿将名字存储在数组中,并在你想要找到索引时编写一个循环遍历它们的方法.