How to: Show Persistent Objects in a Non-Persistent Object's View
- 6 minutes to read
This topic describes how to declare a persistent type reference or collection property in a non-persistent class and display it in the user interface, and optionally assign a default value to it.
- Persistent Reference Property
- Persistent Collection
- Initialize Persistent Property Values
- Important Notes
Persistent Reference Property
Consider the following non-persistent class:
using DevExpress.ExpressApp.DC;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
// ...
[DomainComponent, DefaultClassOptions]
public class NonPersistentObject {
// ...
public string Name { get; set; }
public Person Owner { get; set; }
// ...
}
Note
The INotifyPropertyChanged, IXafEntityObject and IObjectSpaceLink interface implementations were omitted in this example. However, it is recommended to support these interfaces in real-world applications (see PropertyChanged Event in Business Classes and Non-Persistent Objects).
Tip
Use the approach demonstrated in the How to: Perform CRUD Operations with Non-Persistent Objects topic to support saving and loading non-persistent objects from a local cache.
Here, Person is a persistent class from the Business Class Library (for Entity Framework or XPO). Refer to the Add a Class from the Business Class Library (EF) or Add a Class from the Business Class Library (XPO) topic to learn how to add a class from this library. Also, you can use your custom business class instead of Person.
At this stage, the Detail View invoked when creating a new NonPersistentObject, displays the lookup editor for the Owner property. However, the lookup is empty, and you cannot choose any existing Person.
The NonPersistentObjectSpace Object Space created for the current View cannot handle the Person persistent object. You should create an additional Object Space for the Person type and add it to the NonPersistentObjectSpace.AdditionalObjectSpaces collection. You can do this in a module by subscribing to the XafApplication.ObjectSpaceCreated event as follows:
using DevExpress.ExpressApp;
//...
public class NonPersistentModule : ModuleBase {
private void Application_ObjectSpaceCreated(object sender, ObjectSpaceCreatedEventArgs e) {
if(e.ObjectSpace is NonPersistentObjectSpace) {
IObjectSpace additionalObjectSpace = Application.CreateObjectSpace(typeof(Person));
((NonPersistentObjectSpace)e.ObjectSpace).AdditionalObjectSpaces.Add(additionalObjectSpace);
e.ObjectSpace.Disposed += (s, args) => {
additionalObjectSpace.Dispose();
};
}
}
public override void Setup(XafApplication application) {
base.Setup(application);
application.ObjectSpaceCreated += Application_ObjectSpaceCreated;
}
}
The result is demonstrated below.
Persistent Collection
You can add the Owners collection instead of the Owner reference property:
[DomainComponent, DefaultClassOptions]
public class NonPersistentObject{
// ...
public string Name { get; set; }
private IList<Person> owners = new List<Person>();
public IList<Person> Owners {
get {
return owners;
}
}
}
Users can add and remove Owners via the Link and Unlink Actions after adding the code from the previous section.
Initialize Persistent Property Values
Implement the IObjectSpaceLink interface in your non-persistent class and use the IObjectSpace.GetObjects<T> method to get required persistent objects.
[DomainComponent, DefaultClassOptions]
public class NonPersistentObject : IObjectSpaceLink {
public string Name { get; set; }
private Person owner;
public Person Owner {
get {
if (owner == null) {
owner = ObjectSpace.GetObjects<Person>(CriteriaOperator.Parse("FirstName='Sam'")).FirstOrDefault();
}
return owner;
}
set { owner = value; }
}
private IList<Person> owners;
public IList<Person> Owners {
get {
if (owners == null) {
owners = ObjectSpace.GetObjects<Person>(CriteriaOperator.Parse("StartsWith(FirstName, 'B')")) ;
}
return owners;
}
}
private IObjectSpace objectSpace;
[Browsable(false)]
public IObjectSpace ObjectSpace {
get { return objectSpace; }
set { objectSpace = value; }
}
}
If you create a new NonPersistentObject in UI, its Owner property and Owner collection are initialized:
Important Notes
Note the following if your non-persistent class contains persistent properties and implements IObjectSpaceLink.
When loading such an object from a separate NonPersistentObjectSpace, you get the same object instance linking to the initial Object Space via IObjectSpaceLink.ObjectSpace. If this behavior is unwanted, you can update the Object Space in the NonPersistentObjectSpace.ObjectsGetting event handler. Modify the NonPersistentModule class demonstrated in the Persistent Reference Property section as follows:
using DevExpress.ExpressApp;
//...
public class NonPersistentModule : ModuleBase {
private void Application_ObjectSpaceCreated(object sender, ObjectSpaceCreatedEventArgs e) {
if(e.ObjectSpace is NonPersistentObjectSpace) {
IObjectSpace additionalObjectSpace = Application.CreateObjectSpace(typeof(Person));
((NonPersistentObjectSpace)e.ObjectSpace).AdditionalObjectSpaces.Add(additionalObjectSpace);
((NonPersistentObjectSpace)e.ObjectSpace).ObjectGetting += ObjectSpace_ObjectGetting;
e.ObjectSpace.Disposed += (s, args) => {
((NonPersistentObjectSpace)s).ObjectGetting -= ObjectSpace_ObjectGetting;
additionalObjectSpace.Dispose();
};
}
}
private void ObjectSpace_ObjectGetting(object sender, ObjectGettingEventArgs e) {
if(e.SourceObject is IObjectSpaceLink) {
e.TargetObject = e.SourceObject;
((IObjectSpaceLink)e.TargetObject).ObjectSpace = (IObjectSpace)sender;
}
}
public override void Setup(XafApplication application) {
base.Setup(application);
application.ObjectSpaceCreated += Application_ObjectSpaceCreated;
}
}