学习011-04-06 How to: Show Persistent Objects in a Non-Persistent Object‘s View(如何:在非持久性对象的视图中显示持久性对象)

How to: Show Persistent Objects in a Non-Persistent Object’s View(如何:在非持久性对象的视图中显示持久性对象)

This topic describes how to declare a reference or collection property of a persistent type in a non-persistent class and display it in the UI.
本主题介绍如何在非持久类中声明持久类型的引用或集合属性并将其显示在UI中。

Persistent Reference Property(持久引用属性)

Implement the following non-persistent class:
实现以下非持久类:

C#
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 The Importance of Property Change Notifications for Automatic UI Updates and Non-Persistent Objects).
本示例中省略了INotifyPropertyChanged、IXafEntityObject和IObjectSpaceLink接口实现。但是,建议在实际应用程序中支持这些接口(请参阅自动UI更新和非持久性对象的属性更改通知的重要性)。

Tip
Use the approach demonstrated in the How to: Perform CRUD Operations with Non-Persistent Objects topic to support the save and load operations for non-persistent objects.
使用如何:对非持久性对象执行CRUD操作主题中演示的方法来支持非持久性对象的保存和加载操作。

In this example, Person is a persistent class from the Business Class Library. You can use a custom business class instead of Person.
在此示例中,Person是来自Business Class Library的持久类。您可以使用自定义业务类而不是Person。

You can run the application and create a new NonPersistentObject. In its Detail View, the lookup editor for the Owner property is empty and you cannot choose any existing Person.
您可以运行应用程序并创建一个新的非持久性对象。在其详细信息视图中,Owner属性的查找编辑器为空,您不能选择任何现有的Person。
PersistentInNonPresistent1

The NonPersistentObjectSpace created for the current View cannot process the Person persistent object. Follow the steps below to create a persistent Object Space for this type.
为当前视图创建的NonPersistentObjectSpace无法处理Person持久对象。请按照以下步骤为此类型创建持久对象空间。

1.Handle the XafApplication.ObjectSpaceCreated event in a module or Controller.
处理模块或控制器中的XafApplication. ObjectSpaceCreated事件。

2.In the event handler, call the PopulateAdditionalObjectSpaces(XafApplication) method to populate the AdditionalObjectSpaces collection with an additional Object Space that can handle the Person type.
在事件处理程序中,调用PopulateAdditionalObjectSpaces(XafApplication)方法,使用可以处理Person类型的附加对象空间填充AdditionalObjectSpaces集合。

The following example demonstrates how to do this in a platform-agnostic module (MySolution.Module/Module.cs):
以下示例演示了如何在与平台无关的模块(MySolutions. Module/Module.cs)中执行此操作:

C#
using DevExpress.ExpressApp;
//...
public class MySolutionModule : ModuleBase {
    //...
    public override void Setup(XafApplication application) {
        base.Setup(application);
        application.ObjectSpaceCreated += Application_ObjectSpaceCreated;
    }
    private void Application_ObjectSpaceCreated(object sender, ObjectSpaceCreatedEventArgs e) {
        CompositeObjectSpace compositeObjectSpace = e.ObjectSpace as CompositeObjectSpace;
        if (compositeObjectSpace != null) {
            if (!(compositeObjectSpace.Owner is CompositeObjectSpace)) {
                compositeObjectSpace.PopulateAdditionalObjectSpaces((XafApplication)sender);
            }
        }
    }
}

The image below demonstrates the result.
下图演示了结果。
在这里插入图片描述

Persistent Collection(持久收集)

You can add the Owners collection instead of the Owner reference property, as shown below.
您可以添加Owner集合而不是Owner引用属性,如下所示。

C#
[DomainComponent, DefaultClassOptions]
public class NonPersistentObject{
    // ...
    public string Name { get; set; }
    private IList<Person> owners = new List<Person>();
    public IList<Person> Owners {
        get {
            return owners;
        }
    }
}

To allow users to add and remove Owners via the Link and Unlink Actions, create an additional Object Space for the Person type, as demonstrated in the previous section.
要允许用户通过链接和取消链接操作添加和删除所有者,请为Person类型创建一个额外的对象空间,如上一节所示。
在这里插入图片描述

Initialize Persistent Property Values(初始化持久属性值)

Implement the IObjectSpaceLink interface in your non-persistent class and use the IObjectSpace.GetObjects method to get persistent objects.
在非持久性类中实现IObjectSpaceLink接口并使用IObjectSpace. GetObjects方法获取持久性对象。

C#
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using DevExpress.Data.Filtering;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.DC;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
// ...
[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;
        }
        internal set { owners = value; }
    }
    private IObjectSpace objectSpace;
    [Browsable(false)]
    public IObjectSpace ObjectSpace {
        get { return objectSpace; }
        set { objectSpace = value; }
    }
}

If you create a new NonPersistentObject in the UI, its Owner property and Owner collection are initialized.
如果您在UI中创建一个新的非持久性对象,它的Owner属性和Owner集合将被初始化。

在这里插入图片描述

Refresh Linked Persistent Objects(刷新链接的持久对象)

The Refresh Action does not affect non-persistent object Views. Follow the steps below to allow non-persistent objects and persistent objects linked to them to reload.
刷新操作不会影响非持久性对象视图。请按照以下步骤允许重新加载非持久性对象和链接到它们的持久性对象。

1.Access the NonPersistentObjectSpace and set its AutoRefreshAdditionalObjectSpaces property to true.
访问NonPersistentObjectSpace并将其AutoRefreshAdditionalObjectSpaces属性设置为true。

2.Subscribe to the NonPersistentObjectSpace.ObjectGetting event. In the event handler, create a new instance of the non-persistent object and copy property values from the source object. To create copies of persistent objects linked to the non-persistent objects, use the IObjectSpace.GetObject method.
订阅NonPersistentObjectSpace对象获取事件。在事件处理程序中,创建非持久性对象的新实例并从源对象复制属性值。要创建链接到非持久性对象的持久性对象的副本,请使用IObjectSpace. GetObject方法。

C#
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.DC;
using DevExpress.ExpressApp.Xpo;
using DevExpress.Persistent.BaseImpl;
//...
public class MySolutionModule : ModuleBase {
    //...
    public override void Setup(XafApplication application) {
        base.Setup(application);
        application.ObjectSpaceCreated += Application_ObjectSpaceCreated;
    }
    private void Application_ObjectSpaceCreated(object sender, ObjectSpaceCreatedEventArgs e) {
        CompositeObjectSpace compositeObjectSpace = e.ObjectSpace as CompositeObjectSpace;
        if (compositeObjectSpace != null) {
            if (!(compositeObjectSpace.Owner is CompositeObjectSpace)) {
                compositeObjectSpace.PopulateAdditionalObjectSpaces((XafApplication)sender);
            }
        }
        NonPersistentObjectSpace nonPersistentObjectSpace = e.ObjectSpace as NonPersistentObjectSpace;
        if(nonPersistentObjectSpace != null) {
            nonPersistentObjectSpace.AutoRefreshAdditionalObjectSpaces = true;
            nonPersistentObjectSpace.ObjectGetting += ObjectSpace_ObjectGetting;
        }
    }
    private void ObjectSpace_ObjectGetting(object sender, ObjectGettingEventArgs e) {
        var objectSpace = (IObjectSpace)sender;
        if(e.SourceObject is NonPersistentObject) {
            var sourceObject = (NonPersistentObject)e.SourceObject;
            var targetObject = new NonPersistentObject();
            targetObject.Owner = objectSpace.GetObject<Person>(sourceObject.Owner);
            var owners = new List<Person>();
            foreach(var owner in sourceObject.Owners) {
                owners.Add(objectSpace.GetObject<Person>(owner));
            }
            targetObject.Owners = owners;
            e.TargetObject = targetObject;
        }
    }
}

If you modify and save a Person in another View or in a database while the NonPersistentObject Detail View is open, click the Refresh Action to refresh data in this View.
如果在非持久性对象详细信息视图打开时在另一个视图或数据库中修改并保存人员,请单击刷新操作以刷新此视图中的数据。

For a more complex example of a non-persistent object with linked persistent objects, refer to the following GitHub example: How to refresh Non-Persistent Objects and reload nested Persistent Objects.
有关具有链接持久对象的非持久对象的更复杂示例,请参阅以下GitHub示例:如何刷新非持久对象并重新加载嵌套的持久对象。

Important Notes(重要注意事项)

If a non-persistent object implements IObjectSpaceLink and its ObjectSpace property value doesn’t match the Object Space that manipulates the object, the following exception is thrown: ‘An error with the number 1021 has occurred. Error message: The object that was edited belongs to a different ObjectSpace. This error can occur if you manipulate your objects via an ObjectSpace to which these objects do not belong.’
如果非持久对象实现了IObjectSpaceLink,并且其ObjectSpace属性值与操作该对象的Object Space不匹配,则会引发以下异常:“发生了编号为1021的错误。错误消息:编辑的对象属于不同的ObjectSpace。如果您通过这些对象不属于的ObjectSpace操作对象,则可能会发生此错误。”

We recommend that you do not share non-persistent objects when they implement IObjectSpaceLink or have linked persistent objects because of the following limitations.
由于以下限制,我们建议您在实现IObjectSpaceLink或链接了持久对象时不要共享非持久对象。

  • You can use a shared (static) storage for non-persistent objects only if a single NonPersistentObjectSpace works with these objects at any time. Non-persistent objects that implement IObjectSpaceLink cannot belong to multiple Object Spaces simultaneously. When you change the IObjectSpaceLink.ObjectSpace property to a different Object Space, dispose of the previously used Object Space. Otherwise, object changes can trigger events in multiple Views and cause conflicts or unexpected behavior.
    仅当单个NonPersistentObjectSpace在任何时候使用这些对象时,才能对非持久性对象使用共享(静态)存储。实现IObjectSpaceLink的非持久性对象不能同时属于多个对象空间。当您将IObjectSpaceLink. ObjectSpace属性更改为不同的对象空间时,处置以前使用的对象空间。否则,对象更改可能会在多个视图中触发事件并导致冲突或意外行为。

  • You cannot share persistent objects between Object Spaces.
    您不能在对象空间之间共享持久对象。

Instead of sharing non-persistent objects, create new instances in each NonPersistentObjectSpace. If you want to preserve data from all instances of a non-persistent object, store this data separately. See the example in the FeatureCenter.Module\NonPersistentObjects\Controllers.cs file (the NonPersistentObjectSpaceExtender class) in the Feature Center demo that is installed in the %PUBLIC%\Documents\DevExpress Demos 24.1\Components\XAF\FeatureCenter.NETFramework.XPO folder.
不要共享非持久性对象,而是在每个NonPersistentObjectSpace中创建新实例。如果要保留来自非持久性对象所有实例的数据,请单独存储这些数据。请参阅安装在%PUBLIC%\Documents\DevExpress Demos 24.1\Components\XAF\FeatureCenter. NETFramework.XPO文件夹中的FeatureCenter.Module\NonPersistentObjects\Controller.cs文件(NonPersistentObjectSpaceExtender类)中的示例。

For more information, refer to the following Breaking Change description: Core - Error 1021 may occur if a non-persistent object implements IObjectSpaceLink and shared between different Object Spaces.
有关详细信息,请参阅以下重大更改描述:Core-如果非持久对象实现IObjectSpaceLink并在不同对象空间之间共享,则可能会发生错误1021。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汤姆•猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值