NHibernate: Почему Linq First () форсирует только один элемент во всех дочерних и внучатых коллекциях с помощью FetchMany ()

Модель домена

У меня есть канонический домен клиента с множеством заказов , с каждым Заказ с множеством элементов заказа :

Заказчик

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.

  1. Когда сопоставление fetch = "join" , я должен получить декартово произведение между таблицами Customer, Order и OrderItem.
  2. При отображении fetch = "select" я должен получить запрос для клиента, а затем несколько запросов для каждого заказа и OrderItems.

Как это происходит с добавлением метода First () в цепочку, я теряю из виду, что должно происходить.

Выдаваемый SQL-запрос является традиционным запросом с левым внешним соединением с select top (@ p0) впереди.

15
задан rbellamy 17 June 2011 в 21:12
поделиться