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

StackOverflow https://stackoverflow.com/questions/62436

  •  09-06-2019
  •  | 
  •  

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

我有一个 XAF 应用程序,其父类名为 MyParent.

共有 230 条记录 MyParent.

MyParent 有一个名为的子类 MyChild.

有 49,000 条记录 MyChild.

我在之间定义了一个关联 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"); }
}

有一个具体的 MyParent 记录被叫 MyParent1.

为了 MyParent1, 有 630 个 MyChild 记录。

我有一个名为 DetailView 的类 MyUI.

用户在一个下拉列表中选择一项 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 才需要它。我不认为持久化它会加快第一次创建集合的速度,并且在使用它填充下拉列表后,我不需要它,所以我不想花时间存储它。

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

眼镜:

  • 维斯塔商务
  • 8 GB 内存
  • 2.33GHz E6550 处理器
  • SQL Server Express 2005

对于用户来说,等待 DetailView 中众多下拉菜单之一的时间太长。

我花时间勾勒出业务案例,因为我有两个问题:

  1. 如何使关联值加载得更快?

  2. 是否有另一种(简单)方法来对运行速度更快的下拉菜单和 DetailView 进行编程?

是的,你可以说 630 的项目太多,无法在下拉列表中显示,但这段代码花费了很长时间,我怀疑速度与 49,000 成正比,而不是与 630 成正比。下拉列表中的 100 个项目对于我的应用程序来说并不算太多。

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

如果查找大量记录很慢,我会理解,但查找几百条记录应该不会花那么长时间。

有帮助吗?

解决方案

首先,您对这个操作应该花费这么长时间的怀疑是正确的,读操作上的 XPO 应该只增加 30 - 70% 的开销,并且对于这么少量的数据,我们应该谈论毫秒而不是秒。

DevExpress 论坛中提供了一些通用的性能技巧,主要围绕对象缓存、惰性加载与深度加载等,但我认为在您的情况下问题是其他的,不幸的是很难从您的问题中猜测发生了什么,仅可以说,它不太可能是 XPO 的问题,更可能是其他问题,我倾向于查看您的会话创建(这也会创建您的对象缓存)和 SQL 连接代码(IDataStore 的东西),连接是如果主机无法完全解析,并且您没有池化/重用连接,则通常会很慢,此问题可能会加剧。

其他提示

我不确定你为什么要这样做。如果您创建了这样的关联:

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 将在需要时加载它们,并且根本不需要会话管理。

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

我的 SQL 连接正常,并且可以与应用程序中的其他功能配合使用。

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

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

我不确定你的情况,只是想分享一些我使用 XAF 的经验。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top