2012-02-21 65 views
2

我试图在运行通过的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 

我应该把什么,而不是对象,因为一些字段是数字(可能被内部转换为int)和一些arevarchar(可能被内部转换为字符串)。我确实尝试了string,但是在数字字段中引发错误。同样,使用类型var将不会编译。

谢谢。

+0

你想知道返回的数据字段值..? – MethodMan 2012-02-21 18:37:10

+0

是的,每个字段的内容:rdr [0],rdr [1]等 – dotancohen 2012-02-21 18:40:36

+0

基于您的阅读器代码..你是否得到任何有效的数据back dotancohen ..?你的sql语句是什么样子的。 – MethodMan 2012-02-21 18:49:58

回答

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() + " "); 
} 
+0

谢谢!有趣的是,我得到了'方法没有重载'GetValues'接受0个参数'的错误,我会通过文档来看看为什么。但有一个问题:如果在'while'体内rdr引用整个数据记录而不是单个行,那么为什么rdr [0]返回当前迭代行的第一个字段的值?我没有看到在文档中提到的问题。 – dotancohen 2012-02-21 19:53:03

+0

啊,对不起,您需要传入一个数组,其中填充了值。我已经编辑了答案来解释这一点。 – phoog 2012-02-21 20:00:14

+0

@dotancohen索引器'rdr [0]'返回读取器当前行的值;由'GetEnumerator()'返回的枚举器枚举行。为什么?这似乎很不一致。我一直认为这是一个构思不清,混乱的设计;如果有其他人有证据相反,我会很高兴听到它。 – phoog 2012-02-21 20:20:40

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; } 
    } 
+0

谢谢胡安。您链接的博客文章非常出色。可以肯定的是一个有趣的解决方案。 – dotancohen 2012-02-21 19:42:09

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"] + " "); 
      } 
     } 

希望这有助于。

+0

谢谢,佩剑,但是假设你知道字段名称。我正在寻找一种方法来在返回的字段上运行foreach而不知道它们是什么。用例是我在测试和调试时在几个表上运行'SELECT * FROM',因此需要打印这些值的一般情况。谢谢。 – dotancohen 2012-02-21 18:45:12

+0

它是不可能的,我的朋友,至少你应该知道每个表的字段数量,以便通过像'rdr [0]'这样的序号来访问字段的值。 – saber 2012-02-21 18:49:31

+0

谢谢,佩刀,至少我们试过了。投给DBNull,我不知道这件事。谢谢! – dotancohen 2012-02-21 19:38:46

1

i.ToString()调用.ToString()方法(这是虚拟的)在任何类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() + " "); 
} 
+0

是的,我当然绑了代码。值“System.Data.Common.DataRecordInternal”被打印到控制台。这看起来是我的数据类型,而不是价值! – dotancohen 2012-02-21 18:47:21

+0

更新,对不起。错过了你正在迭代行,而不是字段。 – 2012-02-21 18:50:20

+0

增加了一个更多的编辑,使其实际上理智 – 2012-02-21 18:53:39

1

你也可以做这样的事情,例如说你想获得的所有列名的列表,但不知道基础上的DataReader返回的名字.. 你可以创建一个列表

List 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一个逗号分隔的列表,然后列表请执行以下操作:

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

+0

谢谢,CRAZE!你知道什么类型的列表应该是什么?我尝试了'System.Data.Common.DataRecordInternal',但这是一种受保护的类型,我无法将它列出。另外,如果'Console.WriteLine()'之前的行中的变量'columns'实际上应该是'lstColumns'? – dotancohen 2012-02-21 20:03:34

相关问题