KB Article B186657
Visible to All Users

How to separate database tables from built-in system tables via a prefix or custom schema

Problem
It may be required to distinguish or separate service tables used by XAF/XPO applications from other legacy database tables, for instance, by using a table name prefix.

Current (recommended) solutions
If you want to change a table name just for a few custom persistent classes, use PersistentAttribute. To change table names or provide prefixes or different schemas for many tables, consider the following approaches:
1. You can customize the XPO connection provider settings as per How do I map persistent classes to another schema, e.g. other than the default "dbo" in MS SQL Server? This solution appears to be the best and simplest way to avoid any possible naming conflicts with other companies or applications and we recommend you seriously consider it over the next two options.

2.  You can customize type metadata of required persistent classes by adding/removing PersistentAttribute with the desired table name dynamically. Refer to the Customize Business Object's Metadata topic and example below for more information:

C#
public override void CustomizeTypesInfo(ITypesInfo typesInfo) { base.CustomizeTypesInfo(typesInfo); XPDictionary dictionary = XpoTypesInfoHelper.GetXpoTypeInfoSource().XPDictionary; //You can use this code to load missing classes into XPDictionary. However, it is better to do that in the code of your module as follows: this.AdditionalExportedTypes.Add(typeof(DevExpress.ExpressApp.Updating.ModuleInfo)); dictionary.GetClassInfo(typeof(DevExpress.ExpressApp.Xpo.Updating.ModuleInfo)); dictionary.GetClassInfo(typeof(DevExpress.Xpo.XPObjectType)); dictionary.GetClassInfo(typeof(DevExpress.Xpo.XPWeakReference)); foreach (XPClassInfo ci in dictionary.Classes) { if (ci.IsPersistent && (ci.AssemblyName.StartsWith("DevExpress.") || ci is DevExpress.Xpo.Metadata.Helpers.IntermediateClassInfo)) { ci.RemoveAttribute(typeof(PersistentAttribute)); ci.AddAttribute(new PersistentAttribute(string.Format("System_{0}", ci.TableName))); typesInfo.RefreshInfo(ci.ClassType); } } }

For versions prior to 19.2.4, you need to use the code below:

C#
private static Object lockObject = new Object(); private static bool prefixesUpdated; public override void CustomizeTypesInfo(ITypesInfo typesInfo) { base.CustomizeTypesInfo(typesInfo); if (!prefixesUpdated){ lock(lockObject){ if (!prefixesUpdated){ XPDictionary dictionary = XpoTypesInfoHelper.GetXpoTypeInfoSource().XPDictionary; //You can use this code to load missing classes into XPDictionary. However, it is better to do that in the code of your module as follows: this.AdditionalExportedTypes.Add(typeof(DevExpress.ExpressApp.Updating.ModuleInfo)); dictionary.GetClassInfo(typeof(DevExpress.ExpressApp.Xpo.Updating.ModuleInfo)); dictionary.GetClassInfo(typeof(DevExpress.Xpo.XPObjectType)); dictionary.GetClassInfo(typeof(DevExpress.Xpo.XPWeakReference)); foreach (XPClassInfo ci in dictionary.Classes) { if (ci.IsPersistent && (ci.AssemblyName.StartsWith("DevExpress.") || ci is DevExpress.Xpo.Metadata.Helpers.IntermediateClassInfo)) { ci.RemoveAttribute(typeof(PersistentAttribute)); ci.AddAttribute(new PersistentAttribute(string.Format("System_{0}", ci.TableName))); typesInfo.RefreshInfo(ci.ClassType); } } prefixesUpdated = true; } } } }

For more examples, research our internal TableNameCustomizer class code (…\DevExpress.ExpressApp.Xpo\Utils\TableNameCustomizer.cs).

3. You can move the ModuleInfo, XPObjectType and other unwanted system tables into a separate database as described at How to prevent altering the legacy database schema when creating an XAF application.

Please let us know which option works best in your particular case.

Previous (deprecated) solutions
XAF provided the following APIs for this task when XPO is used for data access:
    XafApplication > TablePrefixes
    XafApplication > CustomizeTableName
    XPObjectSpaceProvider > CustomizeTableName

These APIs have a number of constraints that we cannot alter due to backward compatibility (risks of breaking changes to existing customers):
    - No effect on the service XPObjectType and ModuleInfo classes;
    - No effect on persistent classes that already have PersistentAttribute applied explicitly (for instance, certain security system classes like SecuritySystemRole, PermissionPolicyRole, etc.).
We no longer recommend using the TablePrefixes feature in XAF projects due to the aforementioned specifics and also due to the availability of better solutions for the same ultimate goal. With XAF v18.2, these APIs are also marked as internal and we no longer provide formal support for them. If you are happy with these APIs, you can leave your code as is. Your code will operate as before, but these APIs will just disappear from Intellisense and the Application Designer.

Show previous comments (4)

    > Does not the suggested workaround work for you
    You said: "Further research has shown that the TablePrefixes feature does not work for the XPObjectType table."
    Thus the workaround is not a really a workaround.
    > what is the reason for the "ASAP" you mentioned
    Any bug should always be fixed ASAP.

    Dennis Garavsky (DevExpress) 13 years ago

      Thank you for the feedback, Robert.

      DevExpress Support Team 5 years ago

        XAF v19.2.4 ensures that several XafApplication instances do not call the CustomizeTypesInfo method simultaneously. You no longer need the lock statement when you modify Types Info.

        Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

        Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.