Модель домена
У меня есть канонический домен 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;}
}
OrderItems
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 () возвращает Customer.
Изменить 2011-06-17
После дальнейших исследований и размышлений я считаю, что в зависимости от моего отображения эта цепочка методов дает два результата:
.Where(c => c.CustomerID == id)
.FetchMany(c => c.Orders)
.ThenFetchMany(o => o.Items);
ПРИМЕЧАНИЕ. Я не думаю, что смогу получить поведение подвыборки, поскольку я не использую HQL.
- При отображении
fetch="join"
я должен получить декартово произведение между таблицами Customer, Order и OrderItem. - Когда сопоставление равно
fetch="select"
, я должен получить запрос для клиента, а затем несколько запросов каждый для заказов и элементов заказа.
Как это происходит с добавлением метода First () в цепочку, я теряю из виду, что должно происходить.
Выдаваемый SQL-запрос является традиционным запросом с левым внешним соединением с select top (@p0)
впереди.