【问题标题】:SqlDataAdapter.Fill Invalid object name SQLSqlDataAdapter.Fill 对象名称无效 SQL
【发布时间】:2017-07-24 14:54:45
【问题描述】:

我正在尝试将 sql 数据库表中的数据加载到 datagridview 中。

我得到以下信息:

System.Data.dll 中出现“System.Data.SqlClient.SqlException”类型的未处理异常附加信息:无效的对象名称“JournalItems”。

调用时:

SqlDataAdapter.Fill(<dataset here>, <datatable name here>)

我知道 JournalItems 是我数据库中的有效数据表。我也尝试过使用“MyInitialCatalog.dbo.JournalItems”和“MyInitialCatalog.JournalItems”,但没有成功。

这是我的代码:

private void loadData_Click(object sender, EventArgs e)
    {
        string connectionString = "Data Source=myDataSource;Initial Catalog=MyInitialCatalog;Persist Security Info=True;User ID=myID;Password=myPassword";
        string sql = "SELECT * FROM JournalItems";
        SqlConnection connection = new SqlConnection(connectionString);
        connection.Open();
        sCommand = new SqlCommand(sql, connection);
        sAdapter = new SqlDataAdapter(sCommand);
        sBuilder = new SqlCommandBuilder(sAdapter);
        sDs = new DataSet();
        JournalItems = new DataTable();
        sAdapter.Fill(sDs, "JournalItems");
        sTable = sDs.Tables["JournalItems"];
        connection.Close();
        journalItemsDataGridView.DataSource = sDs.Tables["JournalItems"];
        journalItemsDataGridView.ReadOnly = true;
        saveData.Enabled = false;
        journalItemsDataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
    }

PS:这是我要遵循的教程: http://csharp.net-informations.com/datagridview/csharp-datagridview-database-operations.htm

【问题讨论】:

  • 你应该给你的 DataTable 命名 JournalItems : JournalItems = new DataTable("JournalItems");
  • 您是否在调用 Open() 后检查了连接状态是否处于打开状态?也可以尝试只使用 sAdapter.Fill(sDs);
  • 嘿,我确实检查了连接的状态,它是打开的。此外,仅使用 sAdapter.Fill(sDs); 时它仍然给我完全相同的错误;
  • @JonathanWillcock 您在使用数据适配器时不需要打开连接;它会为你做这件事,并把它恢复到后来找到它的状态
  • @CaiusJard 我只是想确保连接字符串没问题!

标签: c# sql datagridview


【解决方案1】:

您的数据集没有名为 "JournalItems" 的表。

代替

JournalItems = new DataTable();

在数据集中创建表:

sDs.Tables.Add("JournalItems");

好吧,事实证明我最初的答案是错误的。如果数据集没有具有指定名称的表,则 dataAdapter 应创建它。

您需要确保连接到正确的数据库和正确的架构。尝试在查询本身中添加数据库名称和架构名称:

SELECT * FROM DataBaseName.SchemaName.JournalItems

我的原始答案的其余部分仍然正确 - 只是现在我已经访问了您正在使用的教程的链接,我需要补充一点,您应该避免使用类级别变量来保存实现 IDisposable 的实例接口 - 因为那样你就不能使用 using 语句并且你最终可能不会释放你应该释放的实例。

SqlConnectionSqlCommandSqlDataAdapterSqlCommandBuilder 都实现了IDisposable 接口,所以你真的应该在using 语句中使用它们。顺便说一句,此代码不需要 SqlCommandBuilder
您的代码应该看起来更像这样:

string connectionString = "Data Source=myDataSource;Initial Catalog=MyInitialCatalog;Persist Security Info=True;User ID=myID;Password=myPassword";
string sql = "SELECT * FROM JournalItems";
sDs = new DataSet();
sDs.Tables.Add("JournalItems");

using(var connection = new SqlConnection(connectionString))
{
    using(var sCommand = new SqlCommand(sql, connection))
    {
        using(var sAdapter = new SqlDataAdapter(sCommand))
        {
            sAdapter.Fill(sDs, "JournalItems");
        }
    }
}
journalItemsDataGridView.DataSource = sDs.Tables["JournalItems"];
journalItemsDataGridView.ReadOnly = true;
saveData.Enabled = false;
journalItemsDataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;

【讨论】:

  • 澄清一下:我不是想向 sD 添加一个名为 JournalItems 的表。 sql 数据库有一个名为 JournalItems 的表,我试图用它来填充数据集 sD。这仍然给我和以前一样的错误。
  • 感谢@Zohar Peled 的更新。正如我在原始问题中提到的那样,我确实尝试使用“DataBaseName.SchemaName.JournalItems”指定表,如下所示:“MyInitialCatalog.dbo.JournalItems”。我的 SchemaName 可能是错误的,因为我只是假设它的 dbo。
【解决方案2】:

PS 这里是我想要学习的教程:http://csharp.net-informations.com/datagridview/csharp-datagridview-database-operations.htm

这是您应该遵循的教程集:

https://msdn.microsoft.com/en-us/library/fxsa23t6.aspx

从“创建一个简单的数据应用程序”开始

为什么我提倡这些而不是您在网络上可以找到的其他内容?并非详尽的原因列表:

  • 您正在使用的编程语言的创建者将它们创建为处理数据集的最佳实践模型
  • 它们适当地抽象(隐藏)了与数据库交互有关的大部分细节,除非您需要降低和肮脏
  • 它将无休止地清理您的代码
  • 它们安全、快速且功能强大;您会自动避开 SQL 注入等大规模安全禁忌
  • 它们比您现在所做的更上一层楼;您不必通过手写语句来放置和设置每个组件的属性来布置窗体:您使用的可视化设计器可提供丰富且专业的编辑体验并生成高质量的代码。这也不例外

如果您接受微软推荐的数据访问方式,您的代码将看起来更像这样:

MyTypedDataSet ds = new MyTypedDataSet();
MyTypedTableAdapter ta = new MyTypedTableAdapter();
ta.Fill(ds, "my where clause parameter value");
myGridview.DataSource = ds.MyTypedTable;

或者,至少:

myGridview.DataSource = new MyTypedTableAdapter().GetXXX();

没有连接字符串,没有充满狡猾 SQL 的按钮单击处理程序;可重用、可维护、易于阅读的代码,无需 100 行即可推动数据库连接的细节

【讨论】:

  • 太棒了!在 13 行代码中,我替换了 235,我的程序也做了同样的事情。作为一个经验不足的年轻开发人员,我很惊讶这是多么无缝。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-22
  • 2018-08-08
相关资源
最近更新 更多