Skip to main content

Data Model Designer

  • 18 minutes to read

XPO ships with the Data Model Designer for editing visual data models created via the Data Model Wizard. The designer allows you to add persistent classes and properties, modify their settings, setup associations, etc.

Note

The ORM Data Model Designer is version-agnostic. You cannot have multiple designer versions on the same machine. We recommend using the latest designer version.

#Overview

The image below illustrates the Data Model Designer and related Visual Studio windows.

Designer_Overview

  • Toolbox. Use it to pick data model elements and place them onto the designer surface.
  • ORMDataModel. This window provides the data model’s tree-like structure. You can use it to find and focus model elements. If the window is hidden, click the VIEW | Other Windows | ORMDataModel menu command to display it.
  • Properties. Displays the focused element’s properties. To edit global properties like the data connection or designed classes’ namespaces, click the empty space in the designer or focus the root Data Model item in the ORMDataModel window.
  • Solution Explorer. Displays designer-generated code stored in the “<MODEL_NAME>Code“ folder. The ConnectionHelper.cs file implements the static ConnectionHelper class that exposes an autocreated connection string and provides methods that simplify Data Access Layer and data store initialization. Other code files contain persistent class implementations. Each persistent class is declared as partial and is split into two files (for example, MyObject.cs, and MyObject.Designer.cs). The designer handles files with the “Designer“ suffix. These files should not be edited manually, as the designer overrides your changes. Place your custom code in a file without the “Designer“ suffix.

#Ways to Invoke

  • To start with a new data model, use the Data Model Wizard. The designer starts automatically when you close the wizard.
  • To design an existing data model, double-click a file with “XPO“ extension in the Solution Explorer.

#Model Properties

To specify data model options, right-click the empty designer’s surface or the root Data Model item in the ORMDataModel window and choose Properties.

Property Description
Collection Properties Type Auto, IList, IList (deprecated), and XPCollection types are available. See the Collection Properties Type section for details.
Data Source Specifies the database connection. Click the ellipsis button to the right of the value to open the corresponding Data Model Wizard page.
Enable nameof Specifies whether to use ‘nameof’ instead of string literals in property accessors.
Field Name Case Specifies the case style for the names of private fields that are encapsulated by persistent properties in the generated code.
Field Name Prefix Specifies the prefix for names of private fields that are encapsulated by persistent properties in the generated code.
Freeze Layout When enabled, prevents the designer from modifying the existing model layout automatically.
Generate Connection Helper Specifies whether the ConnectionHelper class is generated.
Generate Default Constructors Specifies whether the default constructors are generated for persistent classes. When set to false, only the constructor that takes the Session parameter is created for each class. When set to true, the default parameterless constructor is additionally generated.
Generate JSON Serialization Contract Resolver Generate the JsonContract resolver required to use JSON serialization in ASP.NET Core applications
Generate ServiceCollection Extensions Generate extension methods required to use Dependency Injection in ASP.NET Core applications.
Generate Stored Procedures Specifies whether auxiliary helper classes that allow you to call existing stored procedures directly and handle the results are generated.
Generate Views For Table Access Specifies whether persistent classes and DDL (Data Description Language) code required to map database views are generated.
Name Specifies the Data Model name. The names of extension methods in the generated helper classes must include the Data Model name by convention. When the Data Model name is changed, the extension methods are re-created with new names.
Namespace Specifies the namespace for classes the designer generates.
Nullable Behavior Specifies if the IsNullable property of class properties is considered when generating the property code (see the Nullable Behavior section).

#Collection Properties Type

Specifies the default type of collection properties generated by the designer.

  • Auto
    If the type is Auto and the current persistent class supports the GetCollection method, then the designer generates XPCollection<T> collection properties. If the type is Auto and the GetCollection method is not supported (for example, when the base class is PersistentBase), then IList<T> collection properties are generated.
  • IList
    The designer generates IList<T> collection properties according to the new design. This type is compatible with XPCollection properties.
  • IList (deprecated)
    The designer generates IList<T> collection properties according to the deprecated design. IList (deprecated) properties are not compatible with XPCollection properties. You may lose data if you change a collection’s property type from IList (deprecated) to XPCollection.
  • XPCollection
    The designer generates XPCollection<T> collection properties. This type is compatible with IList and not compatible with IList (deprecated). You may lose data if you change a collection’s property type from XPCollection to IList (deprecated); the IList type, however, is safe to use.

#Model Elements

xpo data model designer model elements toolbox

#Persistent Object

Adds a persistent class.

You can specify the following options in the Properties window when a Persistent Object has focus.

Property Description
Base Class Specifies the current persistent class’s base class. You can choose a built-in base class or a class from the DevExpress Business Class Library (available when the DevExpress.Persistent.BaseImpl.Xpo NuGet package is installed or the DevExpress.Persistent.BaseImpl.Xpo.v24.1.dll is referenced in the current project).
To inherit from a custom class, add this class to the designer and define the inheritance relationship instead.
Custom Attributes Specifies custom attributes applied to the current class in the generated code. Use fully qualified attribute names. To apply several attributes at once, provide a comma-separated list.
Deferred Deletion Specifies whether deferred object deletion is enabled for the current persistent class by applying the DeferredDeletionAttribute attribute in the generated code.
Map Inheritance Specifies the type of object-relational inheritance mapping (see MapInheritanceType) for the current persistent class by applying the MapInheritanceAttribute attribute in the generated code.
Member Design Time Visibility Specifies whether the current class is visible at design time by applying the MemberDesignTimeVisibilityAttribute attribute in the generated code.
Name Specifies the persistent class name. Note that when you rename the existing XpObject, the class name changes in code, but the name of the CS or VB file that contains the class implementation does not change. Files are intentionally not renamed to avoid possible conflicts with the version control system.
Non Persistent Specifies whether the class instances will be stored in a persistent data store by applying the NonPersistentAttribute attribute in the generated code.
Nullable Behavior Specifies if the IsNullable property of class properties is considered when generating the property code (see the Nullable Behavior section).
Optimistic Locking Specifies that a persistent object state can be locked during a Session, by applying the OptimisticLockingAttribute attribute in the generated code.
Optimistic Locking Behavior Specifies the locking kind (see OptimisticLockingBehavior), by passing the OptimisticLockingAttribute.LockingKind parameter in the generated code.
Optimistic Locking Read Behavior Specifies field-level optimistic locking settings (see OptimisticLockingReadBehavior) of a persistent object, by applying the OptimisticLockingReadBehaviorAttribute attribute in the generated code.
Persistent Specifies the name of the table mapped to the current class, by applying the PersistentAttribute in the generated code. The table name is passed to the attribute’s PersistentAttribute.MapTo parameter.
Track Properties Modifications On Read Specifies whether modifications made to persistent properties are tracked, by passing the OptimisticLockingReadBehaviorAttribute.TrackPropertiesModifications parameter in the generated code.
XMLDoc Comments Specifies XML documentation tags added to the class declaration.

#Aggregated One-To-Many Relationship

Adds an aggregated one-to-many association between two persistent classes. Applies the AssociationAttribute and AggregatedAttribute attributes in the generated code. To create this association: 1) make sure the N-side persistent class has a persistent property whose Column Type is set to the 1-side class type; 2) focus the ‘One-To-Many Relationship item in the Toolbox; 3) click the 1-side persistent class in the diagram; 4) click the N-side class.

You can specify the following options in the Properties window when an Aggregated One-To-Many Relationship has focus.

Property Description
Name Specifies the association name. The value is passed to the AssociationAttribute in the generated code.
No Foreign Key Specifies whether the automatic creation of the FOREIGN KEY constraints is enabled. When set to true, the NoForeignKeyAttribute is applied in the generated code.
Source Collection Name Specifies the collection property name that is a many side of the association.
Target Property Name Specifies the reference property name that is a one side of the association.

#Calculated Property

Adds a calculated non-persistent property to a persistent class.

You can specify the following options in the Properties window when a Calculated Property has focus.

Property Description
Column Type Specifies the property type.
Custom Attributes Specifies custom attributes applied to the current property. Use fully qualified attribute names. To apply several attributes at once, provide a comma-separated list, for example, “DevExpress.Xpo.Key, System.ComponentModel.Browsable(false)“.
Display Name Specifies the property’s display name. The value is passed to the DisplayNameAttribute attribute in the generated code.
Expression Required. Specifies an expression which determines how the property value is calculated. The expression is passed to the PersistentAliasAttribute in the generated code.
Is Nullable Specifies whether the property type is nullable.
Member Design Time Visibility Specifies whether the property is visible at design time. The value is passed to the MemberDesignTimeVisibilityAttribute in the generated code.
XMLDoc Comments Specifies XML documentation tags added to the property declaration.

#One-To-Many Relationship

Adds a one-to-many association between two persistent classes. Applies the AssociationAttribute attribute in the generated code. To create this association: 1) make sure the N-side persistent class has a persistent property whose Column Type is set to the 1-side class type; 2) focus the One-To-Many Relationship item in the Toolbox; 3) click the 1-side persistent class in the diagram; 4) click the N-side class.

Alternatively, you can create associations of different types using the Persistent Object‘s title bar context menu.

Association_via_contextMenu

You can specify the following options in the Properties window when an Association has focus.

Property Description
Name Specifies the association name. The value is passed to the AssociationAttribute in the generated code.
No Foreign Key Specifies whether the automatic creation of the FOREIGN KEY constraints is enabled. When set to true, the NoForeignKeyAttribute is applied in the generated code.
Source Collection Name Specifies the collection property name that is the many side of the association.
Target Field Name Specifies the reference property name that is the one side of the association.

#Comment

Adds a text comment box.

You can specify the following options in the Properties window when a Comment has focus.

Property Description
Text Specifies the comment text.

Links an existing Comment to a data model element. To create this link: 1) focus the Comment Link item in the Toolbox; 2) click an existing comment in the diagram; 3) click the desired model element.

#Composite Property

Adds a struct-type property that combines properties of a persistent class. To create it: 1) make sure a persistent class has individual properties; 2) drag the Composite Property item from the Toolbox to the persistent class. For legacy database schemas only, not recommended for new projects.

You can specify the following options in the Properties window when a Composite Property has focus.

Property Description
Custom Attributes Specifies custom attributes applied. Use fully qualified attribute names. To apply several attributes at once, provide a comma-separated list, for example, “DevExpress.Xpo.Key, System.ComponentModel.Browsable(false)”“.
Properties Specifies the list of properties that are added to the composite property.
Generate Properties Specifies whether generated structure members are fields or properties.
Key Indicates that a property or a field is a key by applying the KeyAttribute in the generated code.
Name Specifies the property name.
XMLDoc Comments Specifies XML documentation tags added to the property declaration.

#Persistent Property

Adds a persistent property.

You can specify the following options in the Properties window when a Persistent Property has focus.

Property

Description

Column Type

Specifies the property type. If the required type is not available in the combo box, do the following:

  • In the ORMDataModel window, right-click the root Data Model item.
  • Select Add New External Type. A new item will be added to the External Types node.
  • Focus the new External Type item and specify its Name and Namespace in the Properties window.
  • Go back to the persistent property and select the newly added type in the Column Type combo box.

A detailed example on how to add an extra type is provided in the How do I declare an image property in the ORM Data Model Designer article.

Custom Attributes

Specifies custom attributes applied to the current property. Use fully qualified attribute names. To apply several attributes at once, provide a comma-separated list, for example, “DevExpress.Xpo.Key, System.ComponentModel.Browsable(false)”“.

Db Type

Specifies the column type used by the database server for the current property.

Default Value

Specifies the default value of the database column mapped to the target property. The passed value is converted according to the current DBMS specifics and passed to the CREATE TABLE and ALTER TABLE statements when updating the database schema.

DB Default Value

Specifies the SQL expression representing the default value of the database column mapped to the target property. The expression is then passed to the CREATE TABLE and ALTER TABLE statements when updating the database schema.

Delayed

Indicates that the property value will be loaded the first time it is accessed, instead of loading it when the entire persistent object is requested, by applying the DelayedAttribute in the generated code.

Display Name

Specifies the property’s display name. The value is passed to the DisplayNameAttribute attribute in the generated code.

Explict Loading

When greater than zero, objects referenced by the current property are loaded in a single query. It is a recursive process, since the retrieved object might reference other objects. The reference depth of the retrieved object is specified by the Explicit Loading value. The value is passed to the Depth parameter of the ExplicitLoadingAttribute attribute applied in the generated code.

Is Identity

Specifies whether the property type is a key with an autogenerated value, by applying the KeyAttribute with the true parameter.

Is Nullable

Specifies whether the property type is nullable.

Key

Indicates that a property is a key by applying the KeyAttribute in the generated code.

Member Design Time Visibility

Specifies whether the property is visible at design time. The value is passed to the MemberDesignTimeVisibilityAttribute in the generated code.

Name

Specifies the property name.

NonPersistent

Indicates that a property will not be stored in a persistent data store by applying the NonPersistentAttribute in the generated code.

Persistent

Specifies the name of the column mapped to the current property, by applying the PersistentAttribute in the generated. code.

Read Only

Indicates that the property is read-only. When set to true, the property setter is removed.

Fetch Only

Indicates that the property value will not be saved to the database by applying the FetchOnlyAttribute in the generated code.

Size

Specifies the maximum string length supported by the current property, by applying the SizeAttribute in the generated code.

ValueConverter

Specifies the property’s ValueConverter, by applying the ValueConverterAttribute in the generated code.

XMLDoc Comments

Specifies XML documentation tags added to the property declaration.

Note

To reorder properties in a class, drag them with the mouse. Declarations in code will be reordered accordingly.

#Index

Creates a single or multi-column index. Applies the IndexedAttribute or IndicesAttribute attribute.

You can specify the following options in the Properties window when a Index has focus.

Property Description
Properties Specifies properties that affect index creation. The Indexed attribute is applied to the first property in a list. If you specify multiple properties, the IndexedAttribute.AdditionalFields parameter specifies additional columns that affect index creation.
Include GCRecord Specifies whether the GCRecord field is added to the current index.
Include ObjectType Specifies whether the ObjectType field is added to the current index.
Include OptimisticLockField Specifies whether the OptimisticLockField field is added to the current index.
Name Specifies the index name by passing the IndexedAttribute.Name parameter in the generated code.
Unique Specifies whether the index is unique, by passing the IndexedAttribute.Unique parameter in the generated code.

#Inheritance Relationship

Adds an inheritance relationship between two persistent classes. To create this association: 1) focus the Inheritance Relationship item in the Toolbox; 2) click the ‘descendant’ persistent class in the diagram; 3) click the ‘base’ class.

The Data Model Designer can use persistent classes from external assemblies as base classes.

  • Right-click the free space on the designer surface. In the invoked context menu, choose Add Assembly.
  • Select the assembly and click Open.
  • In the Select Types dialog, choose the persistent classes to import from the assembly and click Ok.

These actions will import classes in read-only mode. However, you will be able to use the added classes as ancestors and inherit new persistent classes from them in the designer.

#Many-to-Many Relationship

Adds an many-to-many association between two persistent classes. Applies the AssociationAttribute attribute in the generated code. To create this association: 1) focus the Many-To-Many Relationship item in the Toolbox; 2) click the first persistent class in the diagram; 3) click the second class.

You can specify the following options in the Properties window when a Many-to-Many Relationship has focus.

Property Description
Name Specifies the association name. The value is passed to the AssociationAttribute in the generated code.
Source Collection Name Specifies the FirstObject class’ property name that is a collection of SecondObjects.
Target Collection Name Specifies the name of the SecondObject class’ property that is a collection of FirstObjects.
Use Association Name As Intermediate Table Name Specifies whether the association name is used as a junction table name in a many-to-many relationship, by passing the AssociationAttribute.UseAssociationNameAsIntermediateTableName parameter in the generated code.

#Collection

Added automatically when you declare a one-to-many or many-to-many relationship. Represents the many side of the relationship.

You can specify the following options in the Properties window when a Collection has focus.

Property Description
Custom Attributes Specifies custom attributes applied to the current collection property. Use fully qualified attribute names. To apply several attributes at once, provide a comma-separated list, for example, “DevExpress.Xpo.Key, System.ComponentModel.Browsable(false)”“.
Display Name Specifies the collection’s display name. The value is passed to the DisplayNameAttribute attribute in the generated code.
Explict Loading When greater than zero, objects referenced by the current property are loaded in a single query. It is a recursive process, since the retrieved object might reference other objects. The reference depth of the retrieved object is specified by the Explicit Loading value. The value is passed to the Depth parameter of the ExplicitLoadingAttribute attribute applied in the generated code.
Member Design Time Visibility Specifies whether the collection property is visible at design time. The value is passed to the MemberDesignTimeVisibilityAttribute in the generated code.
Name Specifies the collection property name.
Type Specifies the collection property type. When the type is set to Auto, the Collection Properties Type option of the Data Model is used to determine the collection type to be used in the generated code.
XMLDoc Comments Specifies XML documentation tags added to the property declaration.

#Synchronize the Model with the Database

The IDataStore.AutoCreateOption property specifies whether your application should create new tables and columns in the database (DatbaseAndSchema, SchemaOnly) or throw SchemaCorrectionNeededException (None, SchemaAlreadyExists) if the Data Model and the database schema are different.

If you do not want to allow your application to modify the database schema, consider the following options:

  • Use an SQL script to synchronize the database schema with the modified Data Model. To generate the database update script, open the Data Model Designer, right-click the design surface, and choose the Generate Migration Script menu item. Refer to the Database Schema Migrations knowledge base article for additional information.
  • Use the Data Model Designer to synchronize the Data Model with the modified database schema. To do this, right-click the design surface and choose the Update Model From Database menu item.

The Data Model Wizard generates the static ConnectionHelper.Connect method. Use this method to initialize the data access layer and specify AutoCreateOption.

Note

XPO does not delete tables and columns if you delete classes and properties from the Data Model.

#Nullable Behavior

The designer can generate nullable properties when the NullableBehavior property of the model or class is set to ByUnderlyingType and the IsNullable property of a persistent property is set to True. If the runtime property type allows nulls, the designer adds the NullableAttribute to it. The following table shows what property type is generated depending on the persistent property type, its IsNullable property, and NullableBehavior:

Persistent property type IsNullable AlwaysAllowNulls ByUnderlyingType
All value types true ValueType Nullable<ValueType>
All value types false ValueType ValueType
String true string string
String false string string with the [Nullable(false)] attribute
All reference types except for String any ReferenceType ReferenceType

#Inherit a Class from an Existing Class Declared in Another Library

The designer can retrieve type information from an external assembly:

  1. Right-click the designer surface and select the “Add Assembly“ command.

    XPO model designer add assembly

  2. In the file open dialog, locate the assembly that contains persistent classes, open it, and select classes you want to import into the model.

    XPO model designer select classes

  3. Imported classes will appear in the designer, but they cannot be modified, and no code is generated for them. Use the Inheritance tool from the toolbox to make your declared class inherit from the imported class. The imported class will also appear in the Column Type selection combo box, so you can create a reference property in your class, which will point to the imported class.