Модель домена
У меня есть канонический домен a Customer
со многими Orders
, причем каждый Order
имеет много OrderItems
:
Клиент
public class Customer
{
public Customer()
{
Orders = new HashSet<Order>();
}
public virtual int Id {get;set;}
public virtual ICollection<Order> Orders {get;set;}
}
Заказ
public class Order
{
public Order()
{
Items = new HashSet<OrderItem>();
}
public virtual int Id {get;set;}
public virtual Customer Customer {get;set;}
}
ТоварыЗаказа
public class OrderItem
{
public virtual int Id {get;set;}
public virtual Order Order {get;set;}
}
Проблема
Независимо от того, сопоставлен ли с файлами FluentNHibernate или hbm, я запускаю два отдельных запроса, которые идентичны в их синтаксисе Fetch(), за исключением одного, включающего метод расширения .First().
Возвращает ожидаемые результаты:
var customer = this.generator.Session.Query<Customer>()
.Where(c => c.CustomerID == id)
.FetchMany(c => c.Orders)
.ThenFetchMany(o => o.Items).ToList()[0];
Возвращает только один элемент в каждой коллекции:
var customer = this.generator.Session.Query<Customer>()
.Where(c => c.CustomerID == id)
.FetchMany(c => c.Orders)
.ThenFetchMany(o => o.Items).First();
Я думаю, что понимаю, что происходит здесь, а именно, что метод .First() применяется к каждому из предыдущих утверждений, а не только к исходному предложению .Where(). Это кажется неправильным поведением для меня, учитывая тот факт, что First() возвращает клиента.
Изменить 2011-06-17
После дальнейших исследований и мышления я считаю, что в зависимости от моего сопоставления в эту цепочку методов есть два результата:
.Where(c => c.CustomerID == id)
.FetchMany(c => c.Orders)
.ThenFetchMany(o => o.Items);
ПРИМЕЧАНИЕ. Я не думаю, что могу получить подзапрос, поскольку я не использую HQL.
- Когда отображение
fetch="join"
, я должен получить декартовое произведение между таблицами Customer, Order и OrderItem. - Когда отображение
fetch="select"
, я должен получить запрос для Клиента, а затем несколько запросов для Заказов и OrderItems.
Как это происходит с добавлением метода First() в цепочку, я теряю информацию о том, что должно произойти.
Вывод SQL Query, который выдается, представляет собой традиционный запрос левого внешнего соединения с select top (@p0)
спереди.