我在以下代码中使用SQLite-Net Extensions从Sqlite数据库中检索1000行及其子关系:
var list =
SQLiteNetExtensions.Extensions.ReadOperations.GetAllWithChildren<DataModel>(connection);
问题是性能很尴尬。因为
GetAllWithChildren()
返回的列表不是可枚举的。是否存在使用Sqlite.net扩展将记录加载到Enumerable中的任何方法?我现在使用Sqlite.net中的
Table()
方法,将获取的行加载到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问题,因为它仅执行两个数据库查询。