Skip to content

DevExpress-Examples/XAF_Non-Persistent-Objects-Nested-In-Persistent-Objects-Demo

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

67 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

XAF - How to edit non-persistent objects nested in a persistent object

Often times we are required to store complex data in persistent business objects in compact form (as a string or a byte array), but to show and edit this complex data as objects using standard XAF UI. To address this task in XAF, use non-persistent objects nested in persistent business objects as reference or collection properties. This example demonstrates possible implementations for such scenarios.

To create built-in functionality that can applied to a combination of persistent and non-persistent objects, follow the steps below:

  1. In the common Module, subscribe to the XafApplication.ObjectSpaceCreated event.
  2. Call the CompositeObjectSpace.PopulateAdditionalObjectSpaces method.
  3. Enable the AutoCommitAdditionalObjectSpaces, AutoRefreshAdditionalObjectSpaces, and AutoSetModifiedOnObjectChange options, and set up helpers (adapters) that will handle NonPersistentObjectSpace events.

Warning

We created this example for demonstration purposes and it is not intended to address all possible usage scenarios. If this example does not have certain functionality or you want to change its behavior, you can extend this example. Note that such an action can be complex and would require good knowledge of XAF: UI Customization Categories by Skill Level and a possible research of how our components function. Refer to the following help topic for more information: Debug DevExpress .NET Source Code with PDB Symbols. We are unable to help with such tasks as custom programming is outside our Support Service purview: Technical Support Scope.

Files to Review

Implementation Details

Scenario 1: A non-persistent lookup property

If you have a string field in a persistent business object, you can display this field in the UI using a lookup editor so that a user can choose from existing values or add a new value. The list of existing values is created dynamically.

To implement this scenario, do the following:

  1. This scenario is demonstrated by the Product business object. Add a hidden persistent GroupName string property and a visible non-persistent Group property. The non-persistent Group class defines existing string values and has the Name property that is also a key property.
  2. In the Product class, override the OnLoaded method to create a Group based on the stored GroupName value.
  3. Also, override the OnChanged method to update the GroupName property when the Group property is changed.
  4. To populate the lookup list view, subscribe to the NonPersistentObjectSpace.ObjectsGetting event and collect unique group names from all existing Product objects.

Files to Review

Scenario 2: A nested collection of non-persistent objects stored in the owner persistent object

In this scenario, a persistent business object includes a string field. This field holds a collection of complex data items serialized to XML. You need to display that collection in the UI as a List View (and not as just a text field that contains XML code). This example creates such a List View that allows users to browse and modify the collection and its individual items.

Solution A

  1. This solution is demonstrated by the Project business object. The non-persistent Feature class represents complex collection items. The Feature class has a compound key that consists of the OwnerKey and LocalKey parts. The OwnerKey is used to locate the owner object (Project). The LocalKey is used to identify a Feature object within the collection. These keys are not serialized and exist at runtime only.
  2. The Project class has a hidden persistent FeatureList string property and a visible non-persistent Features aggregated collection property.
  3. Override the OnLoaded and OnSaving methods to serialize and deserialize the Features collection. Note that after deserialization, you should initialize the local key property and the owner key property.
  4. Call the NonPersistentObjectSpace.GetObject method to avoid creation of duplicated objects and to apply deserialized data to the found object.
  5. Subscribe to the IBindingList.ListChanged event of the Features collection to initialize keys of a newly added object and update the persistent FeatureList property whenever the collection is modified.
  6. The NPFeatureAdapter class (derived from the common NonPersistentObjectAdapter helper class) is used to subscribe to NonPersistentObjectSpace events and maintain an object identity map.
  7. In the overridden LoadObjectByKey method (called when the ObjectByKeyGetting event is raised), parse the compound key, locate the owner (Project) using OwnerKey, and search for the desired Feature in its Features collection using LocalKey.
Files to Review

Solution B

  1. This solution is demonstrated by the Department business object. The non-persistent Agent class stores complex collection items and has a simple key.
  2. In WinApplication and WebApplication, descendants override the GetObjectSpaceToShowDetailViewFrom method to reuse the source object space for windows that display Agent objects. This approach simplifies code, but changes made to non-persistent objects in separate windows cannot be undone. As a result, these windows do not have Save and Cancel actions.
  3. The NPAgentAdapter class (derived from the common NonPersistentObjectAdapter helper class) is used to subscribe to NonPersistentObjectSpace events and maintain an object identity map.
Files to Review

Scenario 3: A nested collection of non-persistent objects stored separately

In a persistent business object, you have a string field where we store a sequence of key values. These keys correspond to objects stored elsewhere (in the application model or in an external service). You need to show these objects in the UI as a nested list view and allow users to edit the collection by adding and removing items.

  1. This scenario is demonstrated by the Epoch business object. The non-persistent Technology class represents complex collection items. In this example, a static dictionary stores Technology objects.
  2. The Epoch class has a hidden persistent TechnologyList string property and a visible non-persistent Technologies collection property.
  3. Override the OnLoaded and OnSaving methods to serialize and deserialize the Technologies collection.
  4. After deserialization, call the GetObjectByKey method to load related Technology objects.
  5. The NPTechnologyAdapter class (derived from the common NonPersistentObjectAdapter helper class) is used to subscribe to NonPersistentObjectSpace events and maintain an object identity map.
  6. In the overridden LoadObjectByKey method (called when the ObjectByKeyGetting event is raised), load Technology data from storage and create object instances.
  7. In the overridden CommitChanges method (called when the CustomCommitChanges event is raised), save Technology object data to storage.
Files to Review

Documentation

More Examples

We don't have an EF Core version of this example. If you need this version, please create a ticket in our Support Center and describe your ultimate goal in detail. We will do our best to assist you.

Releases

No releases published

Packages

No packages published

Languages

  • C# 84.6%
  • HTML 14.7%
  • CSS 0.7%