我在访问具有大量记录的关联属性的速度方面存在问题。
我有一个名为MyParent
的父类的XAF应用程序。
MyParent
中有230条记录。
MyParent
有一个名为MyChild
的子类。
MyChild
中有49,000条记录。
我在MyParent
和MyChild
之间以标准方式定义了关联:
在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
条记录。
我有一个名为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秒。
规格:
对于用户来说,等待DetailView中的多个下拉列表之一是太长了。
我花时间勾勒出商业案例,因为我有两个问题:
如何让关联值加载更快?
是否有另一种(简单)方法来编程下拉列表和运行速度更快的DetailView?
是的,你可以说630在下拉列表中显示的项目太多,但是这段代码需要很长时间我怀疑速度与49,000相比而不是630. 100下降的项目-down对我的应用来说不会太多。
我的应用程序中需要相当多的这些下拉菜单,因此强制用户为每个下拉菜单输入更复杂的过滤条件是不合适的。用户需要选择一个值并查看相关值。
我会理解如果找到大量记录的速度很慢,但找到几百个记录的时间不应该那么长。
答案 0 :(得分:2)
首先,你怀疑这个操作应该花费这么长时间是正确的,XPO读取操作应该只增加30-70%的开销,而在这个微小的数据量上我们应该说毫秒而不是秒。 / p>
DevExpress论坛中提供了一些常见的性能提示,并以对象缓存,懒惰与深度负载等为中心,但我认为在您的情况下问题是其他问题,不幸的是,很难再次猜测你的内容是什么问题,只是说,它不太可能成为XPO的问题更有可能成为别的东西,我倾向于看你的会话创建(这也创建你的对象缓存)和SQL连接代码(IDataStore的东西)如果无法彻底解决主机,并且如果您没有联合/重新使用连接,则连接通常很慢,这个问题可能会加剧。
答案 1 :(得分:1)
我不确定你为什么会这样做。如果您创建了这样的关联:
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会根据需要加载它们,并且根本不需要会话管理。
答案 2 :(得分:0)
感谢您的回答。我创建了一个单独的解决方案,并且能够像你建议的那样获得良好的性能。
我的SQL连接正常,可以与应用中的其他功能配合使用。
鉴于我正在使用XAF并且没有做任何额外/花哨的事情,我的会话不是由XAF管理的吗?
我使用的会话是从DetailView中读取的。
答案 3 :(得分:0)
我不确定你的情况,只是想与XAF分享一些经验。
第一次单击下拉列表(查找列表)控件(在详细视图中)时,将有两个查询发送到数据库以填充列表。在我的测试中,有时整个对象被加载到源集合中,而不仅仅是ID和Name属性,因为我们认为这取决于您可能希望使用较轻的列表的对象。您也可以打开列表的服务器模式,然后每次只加载128个对象。