DevExpress eXpressApp框架(XAF)和eXpress持久对象(XPO):如何加快关联的加载时间?

时间:2020-03-05 18:53:20  来源:igfitidea点击:

我在访问具有大量记录的关联属性的速度方面遇到问题。

我有一个XAF应用,其父类名为" MyParent"。

MyParent中有230条记录。

MyParent有一个名为MyChild的子类。

MyChild中有49,000条记录。

我以标准方式在MyParentMyChild之间定义了一个关联:

MyChild中:

// MyChild (many) and MyParent (one)
[Association("MyChild-MyParent")]
public MyParent MyParent;

在MyParent中:

[Association("MyChild-MyParent", typeof(MyChild))]
public XPCollection<MyCHild> MyCHildren
{
     get { return GetCollection<MyCHild>("MyCHildren"); }
}

有一个名为" MyParent1"的特定" MyParent"记录。

对于" MyParent1",有630个" MyChild"记录。

我有一个名为MyUI的类的DetailView。

用户在MyUI DetailView的一个下拉列表中选择一个项目,而我的代码必须用MyChild对象填充另一个下拉列表。

用户在第一个下拉菜单中选择" MyParent1"。

我在MyUI中创建了一个属性,以在第一个下拉列表中为所选值返回MyChild对象的集合。

这是该属性的代码:

[NonPersistent]
public XPCollection<MyChild> DisplayedValues
{
    get
    {
        Session theSession;
        MyParent theParentValue;
        XPCollection<MyCHild> theChildren;

        theParentValue = this.DropDownOne;
        // get the parent value

        if theValue == null)
        {
            // if none

            return null;
            // return null
        }

        theChildren = theParentValue.MyChildren;
        // get the child values for the parent

        return theChildren;
        // return it
    }

我将DisplayedValues属性标记为NonPersistent,因为仅DetailVIew的UI才需要它。我认为持久化它不会在第一时间加快集合的创建,并且在用于填充下拉列表之后,我不需要它,因此我不想花时间存储它。

问题是调用theParentValue = this.DropDownOne需要45秒。

眼镜:

  • Vista商业
  • 8 GB的RAM
  • 2.33 GHz E6550处理器
  • SQL Server Express 2005

对于用户来说,这太长了,无法等待DetailView中的多个下拉菜单之一。

我花了一些时间来草拟业务案例,因为我有两个问题:

  • 如何使关联的值加载更快?
  • 是否有另一种(简单)的方式来对下拉菜单和DetailView进行编程以使其运行得更快?

是的,我们可以说630项太多,无法在下拉菜单中显示,但是这段代码花费的时间太长,我怀疑速度与49,000而不是630成比例。对于我的应用而言,数量不多。

我的应用程序中需要使用这些下拉菜单中的许多下拉列表,因此强制用户为每个表单输入更复杂的过滤条件是不合适的。用户需要选择一个值并查看相关值。

我会知道查找大量记录的速度是否很慢,但是查找几百条记录不应该花那么长时间。

解决方案

回答

首先,我们应该对此操作应该花费这么长时间持怀疑态度,对读操作而言,XPO只会增加30%到70%的开销,而在这样的少量数据上,我们应该说的是毫秒而不是秒。

一些通用的性能提示可在DevExpress论坛上找到,并以对象缓存,延迟与深度加载等为中心,但我认为在情况下,这是另外一回事,不幸的是,很难再次猜测问题的根源,仅比方说,它不太可能是XPO的问题,更可能是其他问题,我倾向于查看会话创建(这也会创建对象缓存)和SQL连接代码(IDataStore的东西),如果无法彻底解决主机问题,并且我们没有建立池/重新使用连接,通常会很慢,此问题可能会加剧。

回答

感谢回答。正如我们所建议的,我创建了一个单独的解决方案,并能够获得良好的性能。

我的SQL连接正常,可以与应用程序中的其他功能一起使用。

鉴于我正在使用XAF并且没有做任何多余的事情,我的会话不是由XAF管理吗?

我使用的会话是从DetailView中读取的。

回答

我不确定为什么会按原样进行。如果我们创建了这样的关联:

public class A : XPObject
{
    [Association("a<b", typeof(b))]
    public XPCollection<b> bs { get { GetCollection("bs"); } }
}

public class B : XPObject
{
    [Association("a<b") Persistent("Aid")]
    public A a { get; set; }
}

然后在我们要填充下拉列表时(例如lookupEdit控件)

A myA = GetSomeParticularA();
lupAsBs.Properties.DataSource = myA.Bs;
lupAsBs.Properties.DisplayMember = "WhateverPropertyName";

我们不必加载A的孩子,XPO会在需要时加载它们,并且根本不需要会话管理。

回答

我不确定情况,只想分享一些我在XAF方面的经验。

第一次单击下拉列表(查找列表)控件(在详细视图中)时,将有两个查询发送到数据库以填充列表。在我的测试中,有时将整个对象加载到源集合中,而不仅仅是ID和Name属性,这取决于我们认为取决于对象的列表,我们可能希望使用较浅的对象。我们也可以打开列表的"服务器模式",则每次仅加载128个对象。