.net 数据层的收益率
我有一个WPF应用程序,它显示DataGrid(XCeed DataGrid)中的项。当数据库(SQLite)包含大量项目时,应用程序需要一段时间才能加载,因此如果可能的话,我想使用yield return按需加载这些项目。我知道,但是我不完全确定如何转换下面的同步代码块 目前,在BackgroundWorker中加载了一个列表,以防止UI减速,该列表作为网格的数据源填充.net 数据层的收益率,.net,wpf,yield-return,xceed-datagrid,.net,Wpf,Yield Return,Xceed Datagrid,我有一个WPF应用程序,它显示DataGrid(XCeed DataGrid)中的项。当数据库(SQLite)包含大量项目时,应用程序需要一段时间才能加载,因此如果可能的话,我想使用yield return按需加载这些项目。我知道,但是我不完全确定如何转换下面的同步代码块 目前,在BackgroundWorker中加载了一个列表,以防止UI减速,该列表作为网格的数据源填充 public override IList<IRecipe> GetRecipes() {
public override IList<IRecipe> GetRecipes()
{
List<IRecipe> recipes = new List<IRecipe>();
Execute(conn =>
{
using (var cmd = conn.CreateCommand()) {
cmd.CommandText = "SELECT * FROM recipes ORDER BY Name";
var reader = cmd.ExecuteReader();
while (reader.Read()) {
try {
var recipe = GetRecipe(reader);
recipes.Add(recipe);
} catch (Exception ex) {
Console.WriteLine(string.Format("Error loading recipe: {0}", ex.Message));
}
}
reader.Close();
cmd.CommandText = "SELECT * FROM Ingredients WHERE Recipe = @Recipe";
cmd.Parameters.AddWithValue("@Recipe", string.Empty);
foreach (IRecipe recipe in recipes) {
cmd.Parameters["@Recipe"].Value = recipe.ID;
reader = cmd.ExecuteReader();
while (reader.Read()) {
try {
IIngredient Ingredient = GetIngredient(reader);
recipe.Ingredients.Add(Ingredient);
} catch (Exception ex) {
Console.WriteLine(string.Format("Error adding Ingredient to recipe '{0}': {1}", recipe.Name, ex.Message));
}
}
reader.Close();
}
}
public覆盖IList GetRecipes()
{
列表配方=新列表();
执行(conn=>
{
使用(var cmd=conn.CreateCommand()){
cmd.CommandText=“按名称从配方顺序中选择*”;
var reader=cmd.ExecuteReader();
while(reader.Read()){
试一试{
var recipe=GetRecipe(读卡器);
配方。添加(配方);
}捕获(例外情况除外){
WriteLine(string.Format(“加载配方时出错:{0}”,例如Message));
}
}
reader.Close();
cmd.CommandText=“从配方=@Recipe的配料中选择*”;
cmd.Parameters.AddWithValue(“@Recipe”,string.Empty);
foreach(配方中的IRecipe配方){
cmd.Parameters[“@Recipe”].Value=Recipe.ID;
reader=cmd.ExecuteReader();
while(reader.Read()){
试一试{
iIngElement成分=获取成分(读取器);
配方。配料。添加(配料);
}捕获(例外情况除外){
WriteLine(string.Format(“向配方“{0}”添加成分时出错:{1}”,配方.Name,ex.Message));
}
}
reader.Close();
}
}
或者,是否有其他方法可以提高速度并使用延迟加载?我不太熟悉xceed如何获取虚拟化项目。
我假设是通过某种事件指定请求的行的范围
在事件(或使用的任何方法)中,您获取查询的一个范围。使用
LIMIT
和OFFSET
,如底部所述。
在这里不是您的朋友。迭代器块(这是yield return
创建的)只是创建一个实现IEnumerable
的类和一个实现状态机的自定义枚举器的语法糖。这实际上并没有提供任何性能优势,也不一定有助于延迟加载,因为它生成的代码与您在其中编写的代码一样同步
我不是Xceed网格方面的专家,因此我无法为您提供该产品特有的答案,但延迟加载确实可以帮助您解决问题(要真正解决这个问题,您可能需要加载尽可能少的数据来显示,然后开始在后台线程中抢先加载即将到来的数据,但是如何做到这一点的细节超出了这里的回答范围)
一种方法可能是同步加载特定数量的行(当时需要显示的任何行),然后根据需要(如果数据集很大,用户不太可能查看所有行)或在后台加载其余行(如果数据集不大或用户可能会查看所有行).您真的需要直接加载所有内容吗?看起来是对的。问题是上一个免费版本(3.1)不支持。需要切换到WPF Toolkit DataGrid。@Echilon:您使用的是.NET的哪个版本?.NET 4.0将
DataGrid
作为标准PresentationFramework
程序集的一部分;WPF Toolkit仅用于.NET 3.x。我已经有一段时间没有使用DataGrid了,这是用于较旧的应用程序。谢谢,tWPF DataGrid似乎提供了一个很有前途的替代解决方案,它使用了异步虚拟化收集
,如下所述