Как я могу предварительно загрузить записи с родительскими и дочерними ссылками с помощью Castle ActiveRecord?
-
07-07-2019 - |
Вопрос
Моя таблица SQL выглядит следующим образом:
CREATE TABLE Page (
Id int primary key,
ParentId int, -- refers to Page.Id
Title varchar(255),
Content ntext
)
и сопоставляется со следующим классом в моей модели ActiveRecord:
[ActiveRecord]
public class Page {
[PrimaryKey]
public int Id { get; set; }
[BelongsTo("Parent")]
public virtual Page Parent { get; set; }
[Property]
public string Title { get; set; }
[Property]
public string Content { get; set; }
[HasMany(typeof(Page), "Parent", "Page")]
public IList<Page> Children { get; set; }
}
Я использую ActiveRecord для извлечения корней деревьев, используя следующий код:
var rootPages = new SimpleQuery<Page>(@"from Page p where p.Parent is null");
return(rootPages.Execute());
Это дает мне правильный граф объектов, но трассировка SQL Profiler показывает, что дочерние страницы загружаются отдельным запросом для каждого неконечного узла в дереве.
Как я могу заставить ActiveRecord загружать весь лот заранее (" SELECT * FROM Page ")
, а затем сортировать объекты в памяти, чтобы получить необходимые отношения родитель-потомок? р>
Решение
Самый простой способ сделать это - извлечь всю таблицу, а затем отфильтровать результат. Это довольно легко, если вы используете linq.
var AllPages = ActiveRecordMediator<Page>.FindAll();
var rootPages = AllPages.Where(p => p.Parent == null);
Другие советы
Попробуйте это:
var rootPages = new SimpleQuery<Page>(@"from Page p left join fetch p.Children where p.Parent is null");
return(rootPages.Execute());
Это приведет к тому, что коллекция Children каждой страницы в наборе результатов будет заполнена во время первоначального запроса, что должно снизить общую нагрузку запроса до одного запроса.