Как оптимизировать вызовы ActiveRecord в ваших веб-приложениях ASP.NET MVC 2?
Я сижу перед своим проектом, и все в порядке, пока я не начну заполнять данные. Как и во многих проектах, у меня есть структура данных, подобная этой:
На планете много стран. В стране много штатов / провинций. В штате много городов. В городе много кварталов.
Ниже приведен пример постоянного бизнес-объекта Castle ActiveRecord / NHibernate
[ActiveRecord]
public class Country {
[Property]
public String CountryName { get; set; }
[HasMany(typeof(States))]
public IList<State> States { get; set; }
}
Теперь предположим, что вы хотите сделать невинный запрос, например, получить список всех стран на планете
По умолчанию ActiveRecord / Nhibernate будет загружать все дерево до самой последней зависимости.
Это может быть ОЧЕНЬ много вызовов SQL.
Хорошо, мы можем решить эту проблему с ленивой загрузкой [ActiveRecord(lazy=true)]
, но потом, когда вы захотите сделать что-то аккуратное, как показано ниже
String text = "This country of " + country.CountryName + " has the following states:";
foreach(State s in country.States)
{
text += s.StateName + " ";
}
С атрибутом отложенной загрузки activerecord каждый раз, когда он выбирает s.StateName, это еще один вызов sql.
Это слишком много вызовов sql.
Некоторые мои друзья предложили использовать методы ActiveRecordBase, такие как FindAll (критерии).
Но в конечном итоге он становится действительно уродливым и трудным для чтения со всеми этими Expression.Eq, а что нет.
А потом другие люди также предложили использовать что-то вроде HQL. HQL выглядит очень похоже на SQL.
Итак, суть в том, что самый чистый и оптимизированный способ - это писать простые и простые SQL-запросы. Это идет прямо к делу.
SELECT * FROM Countries //No loading of an entire tree of dependencies
SELECT * FROM States WHERE CountryId = @selectedId //1 call and you have all your states
В любом случае, сейчас я использую SQL-запросы и хранимые процедуры для извлечения данных и ActiveRecord для сохранения / удаления объектов.
Пожалуйста, поправьте меня, если я ошибаюсь ...?
Спасибо
Оценил.