DevExpress eXpressApp Framework (XAF) et eXpress Persistent Objects (XPO): comment accélérer le temps de chargement des associations?
-
09-06-2019 - |
Question
Je ne parviens pas à accéder rapidement à une propriété d'association comportant un grand nombre d'enregistrements.
J'ai une application XAF avec une classe parente appelée MyParent
.
Il y a 230 enregistrements dans MyParent
.
MyParent
a une classe enfant appelée MyChild
.
Il y a 49 000 enregistrements dans MyChild
.
J'ai une association définie entre MyParent
et MyChild
de manière standard:
Dans MyChild
:
// MyChild (many) and MyParent (one)
[Association("MyChild-MyParent")]
public MyParent MyParent;
Et dans MyParent
:
[Association("MyChild-MyParent", typeof(MyChild))]
public XPCollection<MyCHild> MyCHildren
{
get { return GetCollection<MyCHild>("MyCHildren"); }
}
Il existe un enregistrement MyParent
spécifique appelé MyParent1
.
Pour MyParent1
, il y a 630 enregistrements MyChild
.
J'ai un DetailView pour une classe appelée MyUI
.
L'utilisateur choisit un élément dans un menu déroulant dans le détail MyUI
et mon code doit remplir un autre menu déroulant avec des objets MyChild
.
L'utilisateur choisit MyParent1
dans le premier menu déroulant.
J'ai créé une propriété dans MyUI
pour renvoyer la collection d'objets MyChild
pour la valeur sélectionnée dans le premier menu déroulant.
Voici le code de la propriété:
[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
}
J'ai marqué la propriété DisplayedValues ??
comme Non persistant
car elle n'est requise que pour l'interface utilisateur de DetailVIew. Je ne pense pas que persister accélérera la création de la collection la première fois. Après avoir été utilisé pour remplir la liste déroulante, je n'en ai pas besoin, je ne veux donc pas perdre de temps à la stocker.
Le problème est qu’il faut 45 secondes pour appeler theParentValue = this.DropDownOne
.
Spécifications:
- Vista Business
- 8 Go de RAM
- Processeur E6550 à 2,33 GHz
- SQL Server Express 2005
Cela est trop long pour que les utilisateurs attendent l'une des nombreuses listes déroulantes de la vue détaillée.
J’ai pris le temps d’esquisser le plan d’affaires car j’ai deux questions:
-
Comment puis-je charger les valeurs associées plus rapidement?
-
Existe-t-il un autre moyen (simple) de programmer les menus déroulants et DetailView beaucoup plus rapide?
Oui, vous pouvez dire que 630, c'est trop d'éléments à afficher dans une liste déroulante, mais ce code prend tellement de temps que je soupçonne que la vitesse est proportionnelle à 49 000 et non à 630. 100 éléments dans la liste -down ne serait pas trop pour mon application.
J'ai besoin de plusieurs listes déroulantes dans mon application. Il n'est donc pas approprié de forcer l'utilisateur à entrer des critères de filtrage plus complexes pour chacune d'entre elles. L'utilisateur doit choisir une valeur et voir les valeurs associées.
Je comprendrais si la recherche d’un grand nombre d’enregistrements était lente, mais en trouver quelques centaines ne devrait pas prendre si longtemps.
La solution
Premièrement, vous avez raison de rester sceptique sur le fait que cette opération devrait durer aussi longtemps, XPO sur les opérations de lecture ne devrait ajouter que 30 à 70% de temps système, et sur cette quantité infime de données, nous devrions parler en millisecondes et non en secondes.
Quelques astuces générales sur les perfs sont disponibles sur les forums DevExpress, et sont centrées sur la mise en cache des objets, les charges différées par rapport aux charges profondes, etc., mais je pense que dans votre cas, la question est différente, mais il est malheureusement très difficile de deviner question, seulement pour dire, il est très peu probable que ce soit un problème avec XPO et plus vraisemblablement, je serais enclin à regarder votre création de session (cela créera également votre cache d'objets) et le code de connexion SQL (le matériel IDataStore) , Les connexions sont souvent lentes si les hôtes ne peuvent pas être résolus proprement et si vous ne regroupez / réutilisez pas les connexions, ce problème peut être exacerbé.
Autres conseils
Je ne sais pas pourquoi vous le feriez comme vous êtes. Si vous avez créé une association comme celle-ci:
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; }
}
puis, lorsque vous souhaitez remplir une liste déroulante (comme un contrôle lookupEdit)
A myA = GetSomeParticularA();
lupAsBs.Properties.DataSource = myA.Bs;
lupAsBs.Properties.DisplayMember = "WhateverPropertyName";
Vous n'avez pas besoin de charger les enfants de A, XPO les chargera selon leurs besoins, et aucune gestion de session n'est nécessaire pour cela.
Merci pour la réponse. J'ai créé une solution distincte et j'ai pu obtenir de bonnes performances, comme vous le suggérez.
Ma connexion SQL est correcte et fonctionne avec d'autres fonctionnalités de l'application.
Étant donné que j'utilise XAF et que je ne fais rien d'extraordinaire, mes sessions ne sont-elles pas gérées par XAF?
La session que j'utilise est lue à partir du DetailView.
Je ne suis pas sûr de votre cas, je souhaite simplement partager certaines de mes expériences avec XAF.
La première fois que vous cliquez sur un contrôle de liste déroulante (liste de recherche) (dans une vue détaillée), deux requêtes sont envoyées à la base de données pour remplir la liste. Dans mes tests, il arrive que des objets entiers soient chargés dans la collection source, pas seulement les propriétés ID et Name, car nous pensons que cela dépend de vos objets. Vous pouvez utiliser des objets plus légers pour les listes. Vous pouvez également activer le mode serveur de la liste. Seuls 128 objets sont chargés à chaque fois.