2011-09-28 34 views
1

注意:此問題已解決,但導致new question.NET SQL新表不存在


我得到這個錯誤:

System.Data.SqlClient.SqlException "Invalid object name [tablename]"

我工作的一個數據庫更新與更新部署的產品出貨。第一次運行新更新的應用程序時,數據庫更新會運行,它有兩個主要階段。

  1. Run script update.sql to add new tables to the database
  2. Call some methods to copy some data from existing tables to popuplate the new tables, and do some math/make some adjustments.

第一步完美無瑕。當第二步引用任何新表時,第二步拋出異常。被稱爲異常彈出位置的代碼會在整個(新版本)應用程序中多次使用,並且通常很好。如果這個代碼與舊版本的數據庫一起運行(因爲它使用的表不存在),人們會認爲會發生這個問題,但在這種情況下,表格已經被添加。

更新代碼:

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) 
     { 
     } 
    } 
} 

如上圖所示,異常是由後的表被添加到數據庫被初始化的實體集拋出,但它仍然不承認任何人存在。

有沒有人遇到過這樣的事情?有沒有辦法解決它?

UPDATE
我發現了一些東西,我認爲一定是問題所在。 AppEntities dbOtherClass中的聲明已更改爲private AppEntities db = new AppEntities();,並且它不再在構造函數中初始化,導致它在腳本運行之前創建。不幸的是,解決這個問題仍然會產生同樣的問題

UPDATE
爲了保證數據上下文知道新表,我已經改變了我運行腳本的方式。

之前(正確地執行對數據庫的腳本,應用程序無法找到新表):

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();

UPDATE
使用this question and answer,我是能夠成功地執行使用AppEntities連接的SQL腳本,表也出現在數據庫中。但是,AppEntities(之後腳本已經運行)的類初始化對象仍然會拋出無效對象名的異常。

有沒有辦法強制數據上下文在運行時從數據庫更新自己?

UPDATE(與解決方案):
挖掘到AppEntities(按克里斯·萊弗利的建議)是一個巨大的頭痛,但它確實使我挖掘到一些配置文件爲好。在那裏,我發現新表格被映射到一個單數名稱,而不是複數(TableForEntity而不是TableForEntities),之前它們是複數(當它工作時)。舊桌子也都是複數。在這裏將新表更改爲複數引起各種錯誤,所以我最終改變了SQL腳本以單數命名。令人驚訝的是,這工作。

考慮到以複數命名它們的SQL腳本是基於實際工作的數據庫自動生成的(它們被命名爲複數形式),爲什麼要改變命名工作?如果有的話,那應該導致它修復的問題。

+2

檢查你的腳本。你確定他們的目標是正確的數據庫嗎?交易是否存在? – driis

+0

是的,腳本的目標是正確的數據庫。我在調試時已經打開SQL Management Studio,並且當異常彈出時,我可以驗證這些表確實存在於數據庫中。 – yoozer8

+1

表不會神奇消失。嘗試重複檢查名稱,確保新表格屬於正確的模式等。嘗試使用與應用程序相同的用戶登錄數據庫 - 檢查權限問題。 – driis

回答

1

我不確定AppEntities是什麼,但我相當確信它並不反映新數據庫的結構。

我將猜測它是某種形式的純粹基於數據庫初始版本的生成代碼,並且沒有被recodegen'd(sp?)來保存有關新表的信息。因此,錯誤。

這也可以解釋爲什麼當應用程序在運行之前創建表時,該應用程序在該位置仍然失敗。

總結一下,調查AppEntities並找出它的工作原理。

+0

它基於新表格的新佈局。爲了測試更新腳本,我從數據庫中刪除了新表,然後運行應用程序,然後通過運行sql腳本來添加它們。 – yoozer8

+0

@Jim:似乎RunScript與「OtherClass」完全沒有任何關係。我在說OtherClass不知道你的新表是什麼。 – NotMe

+0

你讓我走上了正軌,我找到了解決方案(詳見問題更新)。然而,它提出了另一個問題,我想我會作爲一個單獨的SO問題提出問題。感謝您的幫助,如果您認爲您可以深入瞭解我在最後提出的問題,那麼一旦它出現,我會將此問題與它聯繫起來。 – yoozer8