У меня есть модель данных по странам, штатам и городам. Каждый городской объект имеет ссылку на штат, а каждый штат имеет ссылку на страну ( диаграмма UML здесь ). Это значительно упрощает мою модель данных.
Для списка городов в пользовательском интерфейсе я извлекаю города из базы данных, используя Nhibernate, и я хочу (1) упорядочить по названию страны (прародителя города) и (2) с нетерпением жду загрузки Вся структура. Я могу заставить NH сделать то же самое, но не оба.
Я получаю:
Запрос указывал выборку соединения, но владелец извлеченной ассоциации не присутствовал в списке выбора [FromElement {явное, не соединение с коллекцией, извлечение соединения, извлечение не ленивых свойств, classAlias = 2, role = , tableName = "Country", tableAlias = country4 , origin = "State" state1_, colums = {state1_.Country_id, className = NHGrandparentSortingSpike.Entities.Country}}] [.ThenFetch [NHGrandparentSortingSpike.Entities.pikeSEngities.pitySpikeSE. Entities.State, NHGrandparentSortingSpike.Entities.Country] (. Fetch [NHGrandparentSortingSpike.Entities.City, NHGrandparentSortingSpike.Entities.State] (. OrderBy [NHGrandparentSortingSpike.Entities.City, System.String] (NHibernate.Linq.NhQueryable`1 [NHGrandparentSortingSpike .Entities.City], Цитировать ((c,) => (c.State.Country.Name)),), Цитировать ((c,) => (c.State)),), Цитировать ((s,) => (s.Country)),)]
Сущность:
public class Country {
public virtual int Id { get; private set; }
public virtual string Name { get; set; }
public virtual IList<State> States { get; set; }
...
}
public class State {
public virtual int Id { get; private set; }
public virtual string Name { get; set; }
public virtual Country Country { get; set; }
public virtual IList<City> Cities { get; set; }
...
}
public class City {
public virtual int Id { get; private set; }
public virtual string Name { get; set; }
public virtual State State { get; set; }
}
Отображения (с использованием Fluent NHibernate):
public class CountryMap : ClassMap<Country> {
public CountryMap() {
Id(x => x.Id).Not.Nullable().GeneratedBy.Native();
Map(x => x.Name).Not.Nullable().Length(100);
HasMany(x => x.States).Inverse().Cascade.All();
}
}
public class StateMap : ClassMap<State> {
public StateMap() {
Id(x => x.Id).Not.Nullable().GeneratedBy.Native();
Map(x => x.Name).Not.Nullable().Length(100);
References(x => x.Country).Not.Nullable();
HasMany(x => x.Cities).Inverse().Cascade.All();
}
}
public class CityMap : ClassMap<City> {
public CityMap() {
Id(x => x.Id).Not.Nullable().GeneratedBy.Native();
Map(x => x.Name).Not.Nullable().Length(100);
References(x => x.State).Not.Nullable();
}
}
Запросы:
Ленивая загрузка с упорядочением (это работает, как и ожидалось, без ошибок, но выдает слишком много SQL-запросов на мой вкус):
var cities = _cityRepo.All.OrderBy(c => c.State.Country.Name);
Стремительная загрузка, но без упорядочивания (работает без ошибок, но не сортируется, поэтому не может быть правильно разбита на страницы):
var cities = _cityRepo.All.Fetch(c => c.State).ThenFetch(s => s.Country);
Стремительная загрузка с заказом (это не работает и выдает ошибку выше):
var cities = _cityRepo.All
.OrderBy(c => c.State.Country.Name)
.Fetch(c => c.State)
.ThenFetch(s => s.Country);
Вот zip простого консольного приложения VS2008, использующего базу данных SQLite в памяти, демонстрирующее эту проблему:
Скачать (2МБ)
Есть идеи?
Спасибо.