2012-05-21 28 views
6

什麼是升級使用ORMDevExpress XPONHibernateMS Entity Framework)數據庫中的最佳做法?的DevExpress XPO VS VS NHibernate的實體框架:數據庫升級問題

我開始一個新的項目,所以必須選擇一個ORM。開發過程需要經常發佈中間測試版本,並且可能每個版本都會在數據庫結構中發生變化。每個新版本都必須輕輕地升級數據庫以保留當前數據。

對於舊的解決方案我會到V3提供了一組SQL腳本從V1數據庫升級到V2,從V2等,並依次執行它們。

但究竟是怎樣爲ORM工作?我還應該編寫SQL腳本來升級數據庫嗎?

我知道簡單地添加新字段不會導致問題(例如,請參閱XPO的UpdateSchema() method),但是如果我必須拆分表並將當前記錄重新分配到2個新表中,該怎麼辦?

回答

6

我不能對其他的ORM的評論,但我自2007年以來,它一直使用DevExpress XPO作爲企業財資應用程序。每次發佈時,架構都會發生一些變化,但多年來也出現了一些大的架構變化。默認XPO升級機制的某種擴展版本可以很好地迎合所有的變化。

有關於升級XPO應用程序的基本信息here

  • DevExpress提供了一個DBUpdater工具來幫助您完成升級生產環境的任務。您可以擴展此工具以滿足其他要求。在我的應用程序中,我們添加了一些日誌記錄選項,回滾預覽等。

  • 每個模塊都有虛擬的UpdateDatabaseBeforeSchemaUpdate()UpdateDatabaseAfterSchemaUpdate()方法。您可以顯着控制這些升級過程。

至於你提到,一些升級會自動XPO處理(例如,添加新列),但有些東西需要額外的控制,例如與現有記錄的默認值初始化新列。

例如,我們假設MyNewField已被添加到您的應用程序2.0版中的MyEntity XPO類中。假設現有記錄的默認值爲3。 XPO將處理新列的創建,但現有記錄將爲NULL。 (如果你在XPO類中指定了一個默認值,它只會涉及新的記錄)。爲了糾正現有記錄的值,你會加入類似以下到實體模塊的重寫UpdateDatabaseAfterSchemaUpdate():(您也可以使用ObjectSpace.GetObjects<MyEntity>()foreach如果你喜歡,以避免直接SQL)

public override void UpdateDatabaseAfterUpdateSchema() 
{ 
    base.UpdateDatabaseAfterUpdateSchema(); 
    if (CurrentDBVersion < new Version(2, 0, 0, 0)) 
     ObjectSpace.GetSession().ExecuteNonQuery(
      "UPDATE [MyEntity] SET [MyNewField] = 3 WHERE [MyNewField] IS NULL"); 
} 

在將表分成兩部分的更極端的例子中,可以使用相同的方法,但是您可以覆蓋UpdateDatabaseBeforeUpdateSchema(),而是運行SQL來拆分表,讓XPO執行任何其他模式更新,並在必要時填充任何默認值爲UpdateDatabaseAfterUpdateSchema()

您會發現碰到約束問題,例如外鍵違規,所以您可能會發現需要編寫一些常規例程,如DropAllForeignKeyConstraints()作爲UpdateDatabaseBeforeUpdateSchema()的一部分。有時你會發現XPO已經提供了一些東西,有時候不會。缺少約束和索引將在模式更新中重新生成。 (根據我的經驗,切換主數據表的主鍵竟然是最難的更新例程。)

默認情況下,調用都發生在SQL事務中,所以如果有任何失敗,它應該全部回滾。

開發人員需要了解何時對域模型進行更改可能會導致底層模式出現問題。

爲了進行測試,我們保留了一些舊的客戶數據庫,並在構建過程中運行一堆前後測試,以確保現有客戶能夠正確升級他們正在升級的任何版本。在生產中,只要遇到問題升級問題,問題數據就會添加到此測試庫中,以防止將來出現類似的問題。

我們正在與主要的國際公司和銀行打交道。客戶對結果非常滿意。在企業的DBA需要簽署變更的情況下,他們似乎並不介意使用命令行工具來執行升級,而不是使用腳本。

+2

您所描述的與XAF有關,而不是專門用於XPO。 – Yuyo

0

大多數遷移解決方案可以處理簡單的任務,例如添加新列,關係或刪除列,但在重命名列時不起作用(是添加?還是刪除添加後等於重命名?你在這種情況下處理數據嗎?)

這三種解決方案都具有基本的遷移支持,甚至可以讓XPO運行自己的腳本作爲過程的一部分(插入靜態/測試/常量數據等)

另外還有MigratorDotNet項目,您可以使用,而不是依賴於有關遷移任何ORM特定的功能。

就個人而言,我會使用自動遷移只能在開發/測試環境和客戶特定數據庫中運行,從V1到V2說升級時,將有全套升級腳本。

+0

感謝您的快速響應。我使用[Apex SQL Tools](http://www.apexsql.com)生成用於升級的SQL腳本。但我擔心的是,用於升級的SQL腳本會使ORM的獨立性與數據庫類型無關。 –

+0

但是記住ORM只是爲了解決另一個問題,即從/向數據庫讀取數據。升級架構只是另一個問題,最好由另一個工具來處理,例如Migrator.NET或外部工具,如Apex SQL Tools。 –

0

它是如何去的ORM工作?我還應該寫SQL腳本到 升級數據庫嗎?

這個問題應該是程序員stackexchange線程明確的答案 - What are the criteria for evaluating an ORM for.NET?,在那裏,我得到了你的問題,你問與我的ORM的經驗相匹配的簡單的答案,同時開發一些項目與實體框架和代碼史密斯ORM模板。

怎樣的ORM管理數據模型的變化?如果我必須拆分表並將當前記錄重新分配到2個新表中,該怎麼辦?

有些不到一定程度的自動更新數據庫,其他 不要做任何事情,你必須做骯髒的工作自己;其他 提供了一個處理更改的框架,可讓您控制數據庫 更新。That means every couple of days有人需要花一個小時更新模型添加表或改變正在改變數據類型

編號:
https://softwareengineering.stackexchange.com/questions/6543/what-are-the-benefits-of-using-database-abstraction-by-orm
https://softwareengineering.stackexchange.com/questions/41739/best-arguments-for-against-introducing-orm-technology-into-a-companies-dev-proce/41833#41833

0

如果您問 - 使用ORM升級數據庫的最佳做法是什麼 - 我的答案是:如果您的應用程序不僅僅是一個愛好者應用程序,請不要使用它。

有很多情況下很多ORM無法爲您的特定數據庫需求提供支持,例如,在創建存儲過程中,創建索引和視圖,甚至編寫索引視圖/物化表,而無需編寫SQL腳本。像在現有表中添加新的不可空列的問題在ORM遷移代碼中比在編寫SQL腳本中更難解決。

像Visual Studio Data Tools這樣的工具可以更好地處理這些問題。