У меня есть канонический домен клиента
с множеством заказов
, с каждым Заказ
с множеством элементов заказа
:
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 () возвращает клиента.
Edit 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-запрос является традиционным запросом с левым внешним соединением с select top (@ p0)
впереди.