【问题标题】:C# Invalid object name ASP.NETC# 无效的对象名称 ASP.NET
【发布时间】:2013-11-25 10:13:16
【问题描述】:

我正在尝试从表 tblEmployees 中将记录检索到我的数据网格视图 dgvEmployees。我不确定出了什么问题,也许是因为语法?但该代码在使用 MS Visual C# 2010 Express(仅限 WinForms)之前已经运行。我目前正在使用 MS Visual Studio (ASP.NET - C#) 创建一个带有 winforms 的网页。这是我的代码:

    SqlConnection sConn;
    SqlDataAdapter daEmp;
    DataSet dsEmp;

    const string sStr = "Server = MYSERVER\\SQLEXPRESS; Database = EMPLOYEES; Integrated Security = SSPI";

    protected void Page_Load(object sender, EventArgs e)
    {
        sConn = new SqlConnection(sStr);
        daEmp = new SqlDataAdapter("Select * from tblEmployees", sConn);
        dsEmp = new DataSet();

        daEmp.Fill(dsEmp, "tblEmployees");

        dsEmp.Tables["tblEmployees"].PrimaryKey = new DataColumn[] { dsEmp.Tables["tblEmployees"].Columns["EmployeeID"] };

        dgvEmployees.DataSource = dsEmp.Tables["tblEmployees"];

    }

这是此行的错误消息(daEmp.Fill(dsEmp, "tblEmployees");

Invalid object name 'tblEmployees'

请帮忙。谢谢!

【问题讨论】:

  • 运行代码的用户(例如为网站的应用程序池设置的身份)是否有权访问数据库?
  • 不看数据库架构就无法回答。然而,这些是探索的可能性: 1) tblEmployees 是否存储在“dbo”以外的模式中? 2)如果将 SQL 复制到 SQL Management express(或任何正在运行的查询)中,您有什么问题吗? 3)您确定要连接到正确的数据库吗? 4) 数据库表不是复数形式吗?
  • 正确的数据库,是的。当我尝试INSERT INTO 时,它会说同样的错误。但是我可以在打开表格时手动添加记录...

标签: c# sql sql-server tsql


【解决方案1】:

错误是指 SQL 查询而不是 DataSet。换句话说,问题不在于 C#。您需要检查您的连接字符串并确保该表存在于数据库中。

daEmp = new SqlDataAdapter("Select * from tblEmployees", sConn);

这个查询不好:Select * from tblEmployees

您可以通过将查询更改为:Select * from IDONTEXIST 来验证这一点

你会看到类似的错误:

无效的对象名称 IDONTEXIST

【讨论】:

    【解决方案2】:

    您现在正在网站上运行应用程序,因此当您在连接字符串中使用 Integrated Security = SSPI 时,将连接到 SQL Server 的用户是在 IIS 中运行您的应用程序池的用户。

    您需要:

    1. 为应用程序池用户授予对数据库的访问权限(对于默认用户来说不是一个好主意)。
    2. 将连接池的用户更改为有权访问数据库的用户。
    3. 在连接字符串中指定有权访问的用户。

    【讨论】:

    • 谢谢,我的问题是我没有在跨数据库查询的连接字符串中提供Initial Catalog
    【解决方案3】:

    您应该首先验证您的连接字符串:

    • 确保它连接到您认为的 SQL Server 实例。
    • 确保它正在为您认为是的数据库中的连接建立数据库上下文。
    • 确保它与您认为的凭据连接。
    • 确保这些凭据映射到您认为应该映射到的 SQL Server 用户
    • 该 SQL Server 用户具有您认为的默认架构,并且在数据库中具有适当的权限。

    几乎可以肯定,您的问题源于上面列出的一个或多个问题。

    如果用于连接的数据库上下文与您想象的不同,您可能找不到您要查找的对象。

    如果您的对象引用不是模式限定的,则您在解析对象引用时可能会遇到问题。 SQL 查询中的对象引用至少应该始终是模式限定的。而不是说

    select * from tblEmployees
    

    你应该说

    select * from dbo.tblEmployees
    

    其中dbo 是拥有该对象的架构。在运行时按以下顺序查找任何非架构限定的对象引用

    1. 首先,在当前用户的默认架构中探测所需名称的对象。
    2. 如果失败,则会在 dbo 架构(“数据库所有者”)中寻找所需名称的对象。

    对于存储过程,查找更复杂:

    1. 探测当前用户在当前数据库中的默认架构。
    2. 探测当前数据库中的“dbo”模式。

    如果存储过程名称以'sp_'开头,

    1. 在“主”数据库中探测当前用户的默认架构。
    2. 探测“master”数据库中的“dbo”架构。

    如果有问题的对象属于另一个模式,除非由所有者模式限定,否则将无法找到它。

    由于多重查找问题,缺少模式限定会阻止执行计划缓存,这意味着每次执行查询时都必须重新编译查询计划。不用说,这...对性能的影响并不理想。

    此外,如果您的数据库用户是“开发人员”并且有问题的开发人员在 6 个月前在开发过程中创建了一个名为“dev.foo”的表或其他对象,您可能会得到……有趣的结果。现在,您正在生产中并以用户“dev”的身份进行连接。执行select * from foo 将优先绑定到dev.foo,而不是DBA 创建的实际生产表“dbo.foo”。您的用户会想知道为什么他们的数据丢失了,或者当您通过 SQL Management Studio 查看应用程序时,您会想知道为什么应用程序会抱怨丢失的列,而这些列似乎都在那里。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多