Scenario
Call StackSystem.InvalidOperationException: The application cannot connect to the specified database, because the database doesn't exist, its version is older than that of the application or its schema does not match the ORM data model structure. To avoid this error, use one of the solutions from the https://www.devexpress.com/kb=T367835 KB Article.
at DevExpress.ExpressApp.XXXApplication.OnDatabaseVersionMismatch(DatabaseVersionMismatchEventArgs args)
at DevExpress.ExpressApp.XafApplication.CheckCompatibilityCore()
at DevExpress.ExpressApp.XafApplication.CheckCompatibility()
Error 1. The application cannot connect to the specified database, because the database doesn't exist, its version is older than that of the application or its schema does not match the ORM data model structure.
This error commonly occurs for one of these reasons:
- the database doesn't exist yet and needs to be created;
- the database schema does not match the ORM data model structure;
- the database version is older than that of the application;
- the database cannot be accessed due to some internal error *unrelated* to the database update or schema compatibility.
Consider one of the following common solutions depending on the situations below.
1.1. If there is an "Inner exception: …" section at the bottom of this message or in the eXpressAppFramework.log file (both production and development environments)
This section usually refers to an internal error unrelated to the database update or schema compatibility. Internal errors can quite often be caused by a misconfigured database server, assembly loading failures, connection string or missing database security permissions for the application user identity.
To avoid these internal errors, try googling the internal error message text for solutions. For instance, you can learn more on this from the Deployment > Deployment Tutorial > Database Security References article and other help sources.
1.2. Production environment (when deploying)
Create or update the database schema as described in the following help topic: Application Update (use the DBUpdater tool for WinForms and WebForms apps or the -updateDatabase -silent -forceUpdate
command for Blazor and Web API Service apps respectively).
1.3. Development environment
Start the application from Visual Studio with the debugger attached, because by default, our new application templates (v15.2+) use a simpler and more convenient way to check database compatibility (see XafApplication.CheckCompatibilityType) and are configured to always update the database when System.Diagnostics.Debugger.IsAttached is true.
C#CheckCompatibilityType = DevExpress.ExpressApp.CheckCompatibilityType.DatabaseSchema;
OR
In the YourSolutionName.Wxx/WxxApplication.xx file, modify the the XafApplication.DatabaseVersionMismatch event handler code to explicitly enable automatic database update on each run:
C#private void MainDemoWinApplication_DatabaseVersionMismatch(object sender, DatabaseVersionMismatchEventArgs e) {
e.Updater.Update();
e.Handled = true;
}
Note: this code modification is suitable for testing during development only. It is NOT suitable for production, because automatic database updates by the main application are not desirable in this case (it is advisable to use separate administrative tools like DBUpdater for that purpose).
Error 2. Database is designed for the A application while you are running the B application
This exception occurs when the XafApplication.CheckCompatibilityType property is set to ModuleInfo and your ApplicationName does not match the application name stored in the ModuleInfo database table. This issue may occur if you changed the ApplicationName property in code after the application was deployed and if the same database is used by multiple XAF applications. Use one of the following solutions to avoid this error:
- If you do not have a special database versioning logic around the ModuleInfo table, set the XafApplication.CheckCompatibilityType property to 'DatabaseSchema' (v15.2+).
- Make sure the XafApplication.ApplicationName property value matches the value stored in the corresponding row of the ModuleInfo database table (a row with the True value in the IsMain column). You can change either one of them. If the database is used by multiple XAF applications, set the XafApplication.ApplicationName property to the same value in all applications. You can apply these changes using the Application Designer or in code.
Error 3. Cannot update the application when the XafApplication.CheckCompatibilityType property is set to DatabaseSchema. Please set this property to ModuleInfo, or disable the application update using the configuration file's NewVersionServer option.
The automatic Application Update mechanism works only when the XafApplication.CheckCompatibilityType property is set to ModuleInfo. In this mode the ModuleInfo table is maintained in the database, which allows the updater to compare actual and expected module versions and trigger the client application update when versions do not match. By default, all new projects use the DatabaseSchema compatibility checking mode. In this mode the ModuleInfo table is not created in the database and automatic application update is not possible. To avoid the issue, either disable the automatic application update by clearing the NewVersionServer value in the configuration or set the CheckCompatibilityType property to ModuleInfo.
Error 4. The client application cannot connect to the Middle Tier Application Server and its database.
When the application server is in use, the compatibility check is performed at the server side. You should unconditionally throw an exception when the XafApplication.DatabaseVersionMismatch event occurs.
If the DatabaseVersionMismatch event handler throws the exception at the client, please ensure that both client and server have the same modules set. Refer to the Visual Studio Output window content or see the client application log (eXpressAppFramework.log). For instance, the following message indicates that the SystemAspNetModule module is not added to the server's Modules collection. (The missing module version is displayed as "0.0.0.0".)
module 'SystemAspNetModule' (DevExpress.ExpressApp.Web.v19.1). Local version: 19.1.6.0, Version on DB: 0.0.0.0
To fix the issue, add this module to the ServerApplication.Modules collection as shown in the Create and Configure the Server topic.
Your feedback is needed
If you experience any difficulties, please contact our Support Team at https://www.devexpress.com/ask and describe in detail how you used the aforementioned solutions for your situation and which actual results or difficulties you had with them.
The most time I get this error, is because the current user has no access to the database (if no application server is used).
With ActiveDirectory Authentication, a XAF user is created automatically, but setting database permissions has to be done manually.
@Joseph: Thanks for sharing. I also hope that you can easily determine the cause of this behavior by the inner exception details.
@Dennis, I have written the code below into production because I am sick of running dbupdater every time I deploy to production and besides, it is impossible to run dbupdater on a cloud (azure) deployment.
e.Updater.Update(); e.Handled = true;
I will let you know how it goes.
My workaround used to be to run the release version in vs against the production db then publish the app without building so that the debug mode triggers update.
@James: Thank you for your feedback. Let's continue this discussion in your original ticket (DBUpdater and Azure Web Services Setting up CI on Visual Studio Online).
Hi Dennis, I have the same issue about DBupdater and azure - do you have any documentation that came out of this ticket you are mentioning (it's private)
Hi,
In the mentioned ticket, we faced an issue that the DBUpdater tool requires user confirmation at several steps. This is not appropriate for automation. To avoid this, DBUpdater has the -silent parameter. If you pass it, no confirmation from a user will be required. Please check the following topic to learn how to pass this parameter: Application Update.
Please let me know if you can use the DBUpdater tool on Azure.
Hi All,
We use the following solutions for many years now with Azure:
if((Control.ModifierKeys & Keys.Shift) != 0) { // <Ctrl>+<Shift> Check ... & Keys.Control if(MessageBox.Show(@"Upgrade database?", @"Confirm Database Upgrade", MessageBoxButtons.YesNo) == DialogResult.Yes) { e.Updater.Update(); e.Handled = true; return; } }
Code is placed within <Your XAF app>_DatabaseVersionMismatch(…)
An other way we no longer use is:
// Dear programmer: // When I wrote this code, only god and // I knew how it worked. // Now, only god knows it! // // Therefore, if you are trying to optimize // this routine and it fails (most surely), // please increase this counter as a warning for the next person: // // total_hours_wasted_here = 254 foreach(var arg in Environment.GetCommandLineArgs()) { if(arg == "/DBUpdate") { e.Updater.Update(); e.Handled = true; return; } }
//counter incremeted manually, as had once been my DB updates total_hours_wasted_here = 257
Love the comments there.
@Gosha - I got mixed up in there, I am running a Blazor app, so not really using the DBUpdater but instead customizing my DatabaseVersionMismatch event
@JeePee [NL] interesting solutions there
So personally I have created a new appsetting (and matching azure app service setting) to say which environment the app is running under (Local VS debugging, Testing app slot in Azure, or Staging, or Production). Basically, it selects a connection string for the appropriate environment and decides whether it should be updated automatically (local and test app slot always updates, whereas production does not).
It is however, only the beginning of a solution… because my bigger issue is I am developing an SaaS app with a single tenant per DB model… So I am having to see about how run batch updates on a constantly evolving list of DBs, potentially also in multiple servers. The plan for now is to perhaps further customize arguments the exe can receive in Program.CS for more complicated scenarios and for reading lists of DBs and connection strings to update multiple DBs. Part of the reason for wanting something that could trigger complex DB update operations from the command line is because my current plan is to do this as part of my Azure DevOps Build/Release Pipelines — like after building the solution, run command shell script for "MySolution.Blazor.Server.exe --updateDatabases --DBList [testDBs.json] --TestingEnvironment --seedData " or whatever other tasks I might want to handle updating whole sets of DBs, creating seed test data on some, etc. Curious to see how other people might have approached this doing XAF on a tenant-per-DB model
PS.: for Gosha: I actually sometimes run the module from the Azure App Console when manually updating for some debugging reason, and never needed the -silent flag, it just does it
Hi,
From what I gather, you managed to get the required behavior. If you still have questions, please elaborate on them.
Yes, thanks. Still tweaking to manage multiple environments, but it does the job.