gpt4 book ai didi

c# - GetAllWithChildren() 性能问题

转载 作者:太空宇宙 更新时间:2023-11-03 18:24:30 24 4
gpt4 key购买 nike

我用了SQLite-Net Extensions在以下代码中从 Sqlite 数据库中检索 1000 行及其子关系:

var list =
SQLiteNetExtensions.Extensions.ReadOperations.GetAllWithChildren<DataModel>(connection);

问题是性能很尴尬。因为 GetAllWithChildren() 返回的是 List 而不是 Enumerable。是否存在使用 Sqlite.net 扩展将记录加载到 Enumerable 的方法?

我现在使用来自 Sqlite.netTable() 方法,将获取的行加载到 Enumerable 中,但我不想使用它,因为它不理解关系并且根本不加载子实体。

最佳答案

GetAllWithChildren患有 N+1 problem ,并且在您的特定情况下,这表现得特别糟糕。你的问题不清楚你在尝试什么,但你可以尝试这些解决方案:

使用filter GetAllWithChildren 中的参数:

您可以使用 filter 而不是将所有对象加载到内存然后进行过滤属性,在内部执行 Table<T>().Where(filter)查询,SQLite-Net 将转换为 SELECT-WHERE子句,所以它非常有效:

var list = connection.GetAllWithChildren<DataModel>(d => d.Name == "Jason");

执行查询然后加载关系

如果您查看 GetAllWithChildren code您会发现它只是执行查询,然后然后 加载现有关系。您可以自己执行此操作以避免自动加载不需要的关系:

// Load elements from database
var list = connection.Table<DataModel>().Where(d => d.Name == "Jason").toList();
// Iterate elements and load relationships
foreach (DataModel element in list) {
connection.GetChildren(element, recursive = false);
}

手动加载关系

要完全解决 N+1 问题,您可以使用 Contains 手动获取关系用外键过滤。这在很大程度上取决于您的实体模型,但看起来像这样:

// Load elements from database
var list = connection.Table<DataModel>().Where(d => d.Name == "Jason").toList();
// Get list of dependency IDs
var dependencyIds = list.Select(d => d.DependencyId).toList();
// Load all dependencies from database on a single query
var dependencies = connection.Table<Dependency>.Where(d => dependencyIds.Contains(d.Id)).ToList();
// Assign relationships back to the elements
foreach (DataModel element in list) {
element.Dependency = dependencies.FirstOrDefault(d => d.Id == element.DependencyId);
}

这个解决方案解决了 N+1 问题,因为它只执行两个数据库查询。

关于c# - GetAllWithChildren() 性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38605324/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com