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

发布于 2024-07-05 07:05:43 字数 2488 浏览 8 评论 0原文

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

我有一个 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 属性标记为 NonPercient,因为只有 DetailVIew 的 UI 才需要它。 我不认为持久化它会加快第一次创建集合的速度,而且用它来填充下拉列表后,我就不需要它了,所以我不想花时间存储它。

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

规格:

  • Vista Business
  • 8 GB RAM
  • 2.33 GHz E6550 处理器
  • SQL Server Express 2005

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

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

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

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

    是否有

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

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

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

I am having a problem with the speed of accessing an association property with a large number of records.

I have an XAF app with a parent class called MyParent.

There are 230 records in MyParent.

MyParent has a child class called MyChild.

There are 49,000 records in MyChild.

I have an association defined between MyParent and MyChild in the standard way:

In MyChild:

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

And in MyParent:

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

There's a specific MyParent record called MyParent1.

For MyParent1, there are 630 MyChild records.

I have a DetailView for a class called MyUI.

The user chooses an item in one drop-down in the MyUI DetailView, and my code has to fill another drop-down with MyChild objects.

The user chooses MyParent1 in the first drop-down.

I created a property in MyUI to return the collection of MyChild objects for the selected value in the first drop-down.

Here is the code for the property:

[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
    }

I marked the DisplayedValues property as NonPersistent because it is only needed for the UI of the DetailVIew. I don't think that persisting it will speed up the creation of the collection the first time, and after it's used to fill the drop-down, I don't need it, so I don't want to spend time storing it.

The problem is that it takes 45 seconds to call theParentValue = this.DropDownOne.

Specs:

  • Vista Business
  • 8 GB of RAM
  • 2.33 GHz E6550 processor
  • SQL Server Express 2005

This is too long for users to wait for one of many drop-downs in the DetailView.

I took the time to sketch out the business case because I have two questions:

  1. How can I make the associated values load faster?

  2. Is there another (simple) way to program the drop-downs and DetailView that runs much faster?

Yes, you can say that 630 is too many items to display in a drop-down, but this code is taking so long I suspect that the speed is proportional to the 49,000 and not to the 630. 100 items in the drop-down would not be too many for my app.

I need quite a few of these drop-downs in my app, so it's not appropriate to force the user to enter more complicated filtering criteria for each one. The user needs to pick one value and see the related values.

I would understand if finding a large number of records was slow, but finding a few hundred shouldn't take that long.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

樱娆 2024-07-12 07:05:43

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

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

Firstly you are right to be sceptical that this operation should take this long, XPO on read operations should add only between 30 - 70% overhead, and on this tiny amount of data we should be talking milli-seconds not seconds.

Some general perf tips are available in the DevExpress forums, and centre around object caching, lazy vs deep loads etc, but I think in your case the issue is something else, unfortunately its very hard to second guess whats going on from your question, only to say, its highly unlikely to be a problem with XPO much more likely to be something else, I would be inclined to look at your session creation (this also creates your object cache) and SQL connection code (the IDataStore stuff), Connections are often slow if hosts cannot not be resolved cleanly and if you are not pooling / re-using connections this problem can be exacerbated.

伤感在游骋 2024-07-12 07:05:43

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

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

I'm unsure why you would be doing it the way you are. If you've created an association like this:

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; }
}

then when you want to populate a dropdown (like a lookupEdit control)

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

You don't have to load A's children, XPO will load them as they're needed, and there's no session management necessary for this at all.

南街九尾狐 2024-07-12 07:05:43

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

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

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

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

Thanks for the answer. I created a separate solution and was able to get good performance, as you suggest.

My SQL connection is OK and works with other features in the app.

Given that I'm using XAF and not doing anything extra/fancy, aren't my sessions managed by XAF?

The session I use is read from the DetailView.

囚我心虐我身 2024-07-12 07:05:43

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

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

I'm not sure about your case, just want to share some my experiences with XAF.

The first time you click on a dropdown (lookup list) control (in a detail view), there will be two queries sent to the database to populate the list. In my tests, sometimes entire object is loaded into the source collection, not just ID and Name properties as we thought so depends on your objects you may want to use lighter ones for lists. You can also turn on Server Mode of the list then only 128 objects are loaded each time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文