【问题标题】:C# - Trying to add row values to list throws InvalidOperationExceptionC# - 尝试将行值添加到列表中抛出 InvalidOperationException
【发布时间】:2017-05-24 11:27:22
【问题描述】:

我想将列的值(即列名)和特定行的行值存储到两个单独的列表中。 ProviderDocument 都是 List<string>。但是由于和Document有类型冲突,我用的是var Document,所以编译器接受了。

var Document = Enumerable.Range(0, dr.FieldCount).Select(dr.GetValue).ToList();之前,以下代码运行良好

OleDbCommand cmd = new OleDbCommand(abfrage, conn);
OleDbDataReader dr;
try
{
    conn.Open();
    dr = cmd.ExecuteReader();
    Provider = Enumerable.Range(0, dr.FieldCount)
                         .Select(dr.GetName)
                         .ToList();
    // Following line will throw exception
    var Document = Enumerable.Range(0, dr.FieldCount)
                             .Select(dr.GetValue)
                             .ToList();
    dr.Close();
    dr.Dispose();
}          
catch (System.InvalidOperationException inv)
{
    MessageBox.Show(inv.Message);
    throw;
}

第一个列表正确存储了列名,但另一个列表抛出InvalidOperationException 并说行或列中都没有值。这对于某些列是正确的(它们是空的)。我用另一个 DB-Table 对其进行了测试,其中每一列/行都有一个值,但在这里我得到了同样的异常。

我做错了什么?

提前致谢!

编辑:

这是两个屏幕截图,显示了阅读器的读取值。

第一个带有列名(值是灰色的,它是敏感数据): first results

第二个是整行的值: read values

【问题讨论】:

    标签: c# enumerable getvalue


    【解决方案1】:

    您需要调用dr.Read() 从结果中读取第一行。

    此外,您在该代码中的Document 是一个被丢弃的局部变量。我猜您想将其分配给同名的属性?您还需要将dr.GetValue() 的结果转换为字符串。

    我想你会想要同时初始化 DocumentProvider 以及调用 AddRange 方法,而不是将它们分配给结果。

    【讨论】:

    • 我尝试了while (dr.Read()) { // var Document = Enumerable.Range(0, dr.FieldCount).Select(dr.GetValue).ToList()); },实际上它将值存储/添加到var Document。另外,就像你说的,Document 被扔掉了。我试过铸造它,但我不知道如何管理它。我也尝试了你的建议,没有成功调用AddRange()-Method。
    • 我想我明白了。此代码正在运行,Document 保留结果:IEnumerable<object> Document;Document = Enumerable.Range(0, dr.FieldCount).Select(dr.GetValue).ToList();。这是正确/最好的方法吗?
    • @Allix,是的,这样可以正常工作。您可以将 Document 设为 IList.
    【解决方案2】:

    试试这个

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data;
    using System.Data.OleDb;
    
    namespace ConsoleApplication57
    {
        class Program
        {
            static void Main(string[] args)
            {
                OleDbConnection conn = new OleDbConnection("Enter Connection String Here");
                string abfrage = "Enter Query Here";
                OleDbCommand cmd = new OleDbCommand(abfrage, conn);
                OleDbDataReader dr;
                List<string> Provider = new List<string>();
                int colIndex = 3;
                try
                {
                    conn.Open();
    
                    dr = cmd.ExecuteReader();
                    while (dr.Read())
                    {
    
                        Provider.Add(dr.GetString(colIndex));
                    }
    
                    dr.Close();
                    dr.Dispose();
                }
    
                catch (System.InvalidOperationException inv)
                {
                    MessageBox.Show(inv.Message);
                    throw;
                }
            }
        }
    }
    

    【讨论】:

    • 我试过while (dr.Read()) { Provider.Add(dr.GetString(colIndex)); },但它又抛出了同样的异常。我真的不明白,因为第一个列表得到了正确的结果。
    • 这似乎是在向 Provider 读取所有行,而 OP 只想读取一行中的所有值。
    • @RobinSalih 是的,正确。我的查询在一行中查找特定值(比如说 ID 5)并返回关联的行以及所有列值。
    • ExcuteReader 没有返回任何行。连接或查询(命令文本)有问题。
    • 我将在 OP 中发布两个屏幕截图,以便您查看阅读器读取的值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    • 2012-02-20
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 2014-10-26
    相关资源
    最近更新 更多