通用数据库字段的数据类型

时间:2012-02-21 18:22:14

标签: c# sql-server

我正在尝试遍历ExecuteReader()返回的行的所有字段,请参见此处:

SqlCommand cmd = new SqlCommand(@"select * from People;", conn);
rdr = cmd.ExecuteReader();
while (rdr.Read()) 
{
    foreach (Object i in rdr) 
    {
        Console.WriteLine(i.ToString() + " ");
    }
}

输出到控制台:

System.Data.Common.DataRecordInternal

我应该放置什么而不是object,因为一些字段是数字的(可能是内部转换为int)和一些isvarchar(可能是内部转换为字符串)。我确实试过了string但是在数字字段上引发了错误。同样,使用类型var将无法编译。

感谢。

5 个答案:

答案 0 :(得分:2)

当您迭代foreach (object i in rdr)时,您正在迭代行而不是列。见the documentation for the data reader's GetEnumerator() method。这就是ToString覆盖返回System.Data.Common.DataRecordInternal的原因:你在整个数据记录上调用ToString(),而不仅仅是其中一个值。

要迭代读者的当前行,请调用GetValues()方法;这个返回一个对应于的对象数组,用当前行的值填充一个对象数组:

while (rdr.Read())  
{
    var items = new object[rdr.FieldCount];
    rdr.GetValues(items);
    foreach (object i in items)  
        Console.WriteLine(i.ToString() + " "); 
}

答案 1 :(得分:1)

通常在执行查询时,您确切知道列数,名称及其类型。我可以看到返回的数字或列更改的情况,甚至是名称,但不是类型。您可以添加一些逻辑(using these helpful extensions):

   while (reader.Read())
    {
        var myObj = new MyType()
        {
            MyNumberValue = reader.GetInt32(0),
            MyStringValue = reader.GetString(1)
        };
        var optValue = default(string);
        reader.TryGetValue("optColName", out optValue);
        myObj.OptionalString = optValue;
    }

这将为每一行构建一个MyType的对象。

    private class MyType
    {
        public int MyNumberValue { get; set; }

        public string MyStringValue { get; set; }

        public string OptionalString { get; set; }
    }

答案 2 :(得分:1)

假设您的表中有3个字段

        Id     int,
        Name   nvarchar(64),
        Family nvarchar(64),
        Salary bigint

现在你必须阅读每个字段

        var rdr = cmd.ExecuteReader();
        while (rdr.Read()) {
            if (!(rdr["Id"] is DBNull))
            {
                Console.WriteLine(rdr["Id"] + " ");
            }
            if (!(rdr["Name"] is DBNull))
            {
                Console.WriteLine(rdr["Name"] + " ");
            }
            if (!(rdr["Family"] is DBNull))
            {
                Console.WriteLine(rdr["Family"] + " ");
            }
        }

希望得到这个帮助。

答案 3 :(得分:1)

i.ToString()在该迭代中实现的任何类.ToString()上调用i方法(虚拟)。

如果i是值为5的整数,则应打印" 5" (因为Int32重写.ToString()以返回格式化为String的整数值)。

如果我是一个价值为"纽约"的字符串,它应该打印"纽约" (因为String会覆盖.ToString()以返回this

编辑:道歉,我错过了你在迭代行而不是字段。试试这个:

rdr = cmd.ExecuteReader();
while (rdr.Read()) 
{
    for (var v = 0; v < rdr.FieldCount; v++)
        Console.WriteLine(rdr[v].ToString() + " ");
}

答案 4 :(得分:1)

你也可以做这样的事情,比如说你想获得所有列名的列表,但不知道基于DataReaders返回的名字。 你可以创建一个列表

列出lstColumns = new List();

for (int intCounter = 0; intCounter < reader.FieldCount; intCounter++)
{

  lstColumns.Add(reader.GetName(intCounter));
  columns.Add(string.Join(",",reader.GetName(intCounter).ToArray().ToString().ToList()));
  Console.WriteLine(lstColumns[intCounter]);
}
完成后,

处理lstColumns ..

这将为您提供逗号分隔的FieldNames列表,然后如果要将基于相同构造的数据附加到List,请执行以下操作

如果您只想要字段名称,这是否有意义??