按列名获取SqlDataReader的值(而不是序号)

47
使用 SqlDataReader 的方法,我可以通过传递列的序号来获取该列的值,例如如果我传递read.GetValue(0),则可以获得第一列的值,如果传递read.GetValue(1),则可以获得第二列的值。
在查看这些方法时,我没有看到通过列名称(例如ColumnID)获取列值的选项。在我的虚构示例中,我想要传递read.GetValueofColumn("ColumnID")并读取该列的值(请注意,从方法列表中可以看出,GetValueofColumn方法不存在)。
我是否忽略了执行此操作的方法或方式?

尝试使用“read.GetValue [“ColumnName”]”。 - Tomer Klein
我已经尝试过了,不幸的是 GetValue 只接受一个 int - user9927
1
为什么不直接通过 dataReader["ColumnName"] 获取你要查找的值呢?这并不是那么简单的事情... 这里有一个很好的网站,可以加入你的工具库:C# Get DataReader values by Column Name - MethodMan
6个回答

87
您可以使用GetOrdinal方法获取列的序号,因此您的调用可能是:
read.GetValue(read.GetOrdinal("ColumnID"));

1
非常好,谢谢;我会在8分钟后接受答案。 - user9927
6
出于性能的考虑,微软现在建议您在读取循环外调用GetOrdinal方法,并且仅在循环内部调用GetValue(int)方法。 - Guy Schalnat
2
很棒的答案,然而使用 read.GetFieldValue<YourType>(read.GetOrdinal("ColumnID")); 将为您节省强制转换。 - Hesham Yassin
这个问题我来晚了。只想补充一下,如果您的选择列表列使用AS子句为具有相同名称的列命名,则应小心。在这种情况下,外部GetValue()调用可能会获取潜在不同列的值。 - vitaminjeff

38
< p >Datareader 有基于位置的数值方法和基于字段名称的文本方法。因此,通过字段名称,您可以获取该值。


object value = reader["some field name"];
< p >(假设reader是一个datareader


assuming that reader is a datareader

2
真的,但是其他辅助函数只接受int类型参数,所以如果你想使用它们,你必须调用GetOrdinal(最好在读取循环之外)来获取索引,然后你可以在读取循环内调用任何函数(包括reader[index])。 - Guy Schalnat
4
问题是“通过传递列名获取列值的选项”,我认为我的答案最简单。 - Emanuele Greco

16

回答晚了,但是......这个方法一直对我有用,并且我认为它更接近于OP试图实现的目标:

using (SqlCommand cmd = new SqlCommand(cmdString, cn))
using (SqlDataReader rs = cmd.ExecuteReader()) {

    if (rs.HasRows) {

        while (rs.Read()) {

            Meeting_DiscussionItems_MX di = new Meeting_DiscussionItems_MX();

            di._Discussion_Item_MX_ID   = (int) rs["Discussion_Item_MX_ID"];
            di._Meeting_ID              = (int) rs["Meeting_ID"];
            di._Discussion_Item_Name    = (string) rs["Discussion_Item_Name"];
            di._Display_Order           = (string) rs["Display_Order"];
            di._Status                  = (string) rs["Status"];
            di._Discussion_Items        = (string) rs["Discussion_Items"];
            di._ETOPS_Items             = (string) rs["ETOPS_Items"];
            di._Followup                = (string) rs["Followup"];
            di._Pinned                  = (string) rs["Pinned"];
            di._Active                  = (string) rs["Active"];

            _Meeting_DiscussionItems_MX.Add(di);
        }

    }
}

这样做有什么不利之处吗? - David Mays
到目前为止,这对我来说不适用。如果您的列中可能存在null值,则需要使用DBNull.Value进行检查。 - KWallace

7

为了方便起见,您可以添加一些辅助程序,例如:

public static string GetString(this SqlDataReader reader, string name) {
    return GetFieldValue<String>(reader, name, (string)null);
}

public static T GetFieldValue<T>(this SqlDataReader reader, string fieldName, T defaultvalue = default(T)) {
    try {
        var value = reader[fieldName];
        if (value == DBNull.Value || value == null)
            return defaultvalue;
        return (T)value;
    } catch (Exception e) {
        //SimpleLog.Error("Error reading databasefield " + fieldName + "| ", e);
    }
    return defaultvalue;
}

正如您所看到的,读取器允许使用字段名称,但它返回一个需要转换为正确数据类型的对象。扩展程序会同时处理这两个问题,并为字段为空时添加默认值。


4

您可以使用:

MySqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
    Console.WriteLine(rdr["id"] + " -- " + rdr["time"]);
}
rdr.Close();

其中idtime是列名。


2

您必须按照以下方式使用,将“(string)”替换为您必须使用的类型:

(string) reader["name"];

(说明:该段文字是关于在IT技术中如何使用代码的简单描述。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接