This example shows how to keep the legacy database schema intact when creating an XAF application. Sometimes our customers want to connect their XAF applications to legacy databases, but they often have strong restrictions that disallow any changes in the legacy database schema, i.e. adding new tables, columns, etc. However, depending on the configuration, XAF may need to create additional tables. If the XafApplication.CheckCompatibilityType property is set to CheckCompatibilityType.ModuleInfo, the ModuleInfo table is used to track module versions. If you are using the Security System, additional tables are created to store users, roles, and permissions. XPO itself can add the XPObjectType table to correctly manage table hierarchies when one persistent object inherits another. Usually, legacy databases contain plain tables that can be mapped to one persistent object. So, the XPObjectType table is not necessary in such scenarios.
In this example, we customize the data storage mechanism to store the ModuleInfo and XPObjectType tables in a temporary database.
For this task we introduced a custom IDataStore implementation, which works as a proxy. This proxy receives all the requests from the application's Session objects to a data store, and redirects them to actual XPO data store objects based upon a table name that has been passed.
Steps to implement
1. In YourSolutionName.Module project create a custom IDataStore implementation as shown in the WinWebSolution.Module\XpoDataStoreProxy.xx file;
2. In YourSolutionName.Module project create a custom IXpoDataStoreProvider implementation as shown in the WinWebSolution.Module\XpoDataStoreProxyProvider.xx file;
3. In YourSolutionName.Module project locate the ModuleBase descendant and modify it as shown in the WinWebSolution.Module\Module.xx file;
4. Define connection strings under the <connectionStrings> element in the configuration files of your WinForms and ASP.NET executable projects as shown in the WinWebSolution.Win\App.config and WinWebSolution.Win\Web.config files.
1. The approach shown here is intended for plain database tables (no inheritance between your persistent objects). If the classes you added violate this requirement, the exception will occur as expected, because it's impossible to perform a query between two different databases by default.
2. One of the limitations is that an object stored in one database cannot refer to an object stored in another database via a persistent property. Besides the fact that a criteria operator based on such a reference property cannot be evaluated, referenced objects are automatically loaded by XPO without involving the IDataStore.SelectData method. So, these queries cannot be redirected. As a solution, you can implement a non-persistent reference property and use the SessionThatPointsToAnotherDatabase.GetObjectByKey method to load a referenced object manually.
3. As an alternative to the demonstrated proxy solution you can consider solutions based on database server features. Create a view mapped to a table in another database as a Synonym. Then map a regular persistent class to this view (see How to: Map a Database View to a Persistent Class).