.NET SQL新表不存在

时间:2011-09-28 20:24:25

标签: c# sql entity-framework asp.net-mvc-2 ado.net

注意:此问题已得到解决,但会导致new question


我收到了这个错误:

  

System.Data.SqlClient.SqlException“无效的对象名称[tablename]”

我正在进行数据库更新,以便对已部署产品进行更新。第一次运行新更新的应用程序时,数据库更新会运行,并且它有两个主要阶段。

  
      
  1. 运行脚本update.sql以将新表添加到数据库中
  2.   
  3. 调用一些方法从现有表中复制一些数据以填充新表,然后进行一些数学运算/进行一些调整。
  4.   

第一步完美无瑕。只要引用任何新表,第二步就抛出上面的异常。弹出异常的代码在整个(新版本)应用程序中多次使用,通常很好。如果这个代码与旧版本的数据库一起运行(因为它使用的表不存在),人们会发现会出现这个问题,但在这种情况下,表刚刚添加。

更新代码:

internal void Update()
{
    RunScript(); //runs the SQL script, adds tables to the db

    OtherClass oc = new OtherClass();
    oc.PrepData(); //no error, just makes some minor tweaks to existing table
    oc.CopyData(); //throws exception, none of the new tables appear to exist
    oc.AdjustData(); //manipulates the data in the new table, probably throws exception but currently unreachable
}

public class OtherClass
{
    private AppEntities db;

    public OtherClass()
    {
        db = new AppEntities();
        //other constructor activity
    }

    internal void CopyData()
    {
        foreach(DataItem di in db.DataItems) //This throws the exception (with any of the new tables)
        {
        }
    }
}

如上所示,在将表添加到数据库之后,初始化的实体集抛出了异常,但它仍然不承认它们中的任何一个存在。

有人遇到过这样的事吗?有办法吗?

更新
我发现了一些我认为一定是问题的东西。 AppEntities dbOtherClass的声明已更改为private AppEntities db = new AppEntities();,并且不再在构造函数中初始化,导致在脚本运行之前创建它。不幸的是,解决这个问题仍然会产生同样的问题。

更新
为了确保数据上下文知道新表,我改变了运行脚本的方式。

以前(针对数据库正确执行的脚本,应用程序找不到新表):

StreamReader sr = new StreamReader(File.Open(String.Format("{0}/Scripts/CURRENTVERSION.sql", AppDomain.CurrentDomain.BaseDirectory), FileMode.Open));
string UpdateScript = sr.ReadToEnd();
sr.Close();

//Here connectionstring was the database's connection taken from the .edmx file and trimmed of arguments that caused exceptions as invalid
SqlConnection connection =  new SqlConnection(connectionstring);

SqlCommand command = new SqlCommand(UpdateScript);
connection.Open();
command.ExecuteNonQuery();
connection.Close();

目前:

StreamReader sr = new StreamReader(File.Open(String.Format("{0}/Scripts/CURRENTVERSION.sql", AppDomain.CurrentDomain.BaseDirectory), FileMode.Open));
string UpdateScript = sr.ReadToEnd();
sr.Close();

System.Data.Common.DbCommand command = db.Connection.CreateCommand();
command.CommandText = UpdatScript;
//command.CommandText = @UpdateScript;
db.Connection.Open();
command.ExecuteNonQuery();

我已尝试过注释和未注释的行(带/不带@),但它声称脚本中的每一行都有语法错误(这是第一个方法执行完美的相同脚本)。     db.Connection.Close();

更新
使用this question and answer,我能够使用AppEntities连接成功执行SQL脚本,并且表确实出现在数据库中。但是,AppEntities(在
脚本运行之后初始化的类的对象)仍会抛出无效对象名称的异常。

有没有办法强制数据上下文在运行时从数据库中更新自己?

更新(有解决方案):
深入研究AppEntities(根据Chris Lively的建议)是一个令人头疼的问题,但它确实让我开始深入研究一些配置文件。在那里,我发现新表格被映射到一个单数名称,而不是复数(TableForEntity而不是TableForEntities),之前它们是复数(当它工作时)。旧表也都是复数。在这里将新表更改为复数会导致各种错误,因此我最终只更改了SQL脚本以单数形式命名它们。令人惊讶的是,这很有效。

考虑到以复数命名它们的SQL脚本是基于实际工作的数据库(它们被命名为多个)自动生成的,为什么要更改命名工作?如果有的话,应该导致它修复的问题。

1 个答案:

答案 0 :(得分:1)

我不确定AppEntities是什么,但我非常有信心它不能反映新数据库的结构。

我将猜测它是某种形式的生成代码,它纯粹基于数据库的初始版本,并且没有重新编码(sp?)来保存有关新表的信息。因此,错误。

这也可以解释为什么在你甚至运行之前创建表时,应用程序仍然在同一位置失败。

总而言之,调查AppEntities并确切了解该事情是如何运作的。