注意:此问题已得到解决,但会导致new question。
我收到了这个错误:
System.Data.SqlClient.SqlException“无效的对象名称[tablename]”
我正在进行数据库更新,以便对已部署产品进行更新。第一次运行新更新的应用程序时,数据库更新会运行,并且它有两个主要阶段。
- 运行脚本update.sql以将新表添加到数据库中
- 调用一些方法从现有表中复制一些数据以填充新表,然后进行一些数学运算/进行一些调整。
醇>
第一步完美无瑕。只要引用任何新表,第二步就抛出上面的异常。弹出异常的代码在整个(新版本)应用程序中多次使用,通常很好。如果这个代码与旧版本的数据库一起运行(因为它使用的表不存在),人们会发现会出现这个问题,但在这种情况下,表刚刚添加。
更新代码:
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 db
中OtherClass
的声明已更改为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脚本是基于实际工作的数据库(它们被命名为多个)自动生成的,为什么要更改命名工作?如果有的话,应该导致它修复的问题。
答案 0 :(得分:1)
我不确定AppEntities是什么,但我非常有信心它不能反映新数据库的结构。
我将猜测它是某种形式的生成代码,它纯粹基于数据库的初始版本,并且没有重新编码(sp?)来保存有关新表的信息。因此,错误。
这也可以解释为什么在你甚至运行之前创建表时,应用程序仍然在同一位置失败。
总而言之,调查AppEntities并确切了解该事情是如何运作的。