Несколько выборок в linq to nhibernate - PullRequest
20 голосов
/ 06 марта 2011

Я смотрел на это

Будьте осторожны, чтобы не получить с нетерпением несколько свойств коллекции на в то же время. Хотя это утверждение будет работать нормально:

вар сотрудников = session.Query () .Fetch (e => e.Subordinates) .Fetch (e => e.Orders) .ToList ();

Мне нужно получить 2 ссылки, поэтому мне нужно сделать что-то подобное. Есть ли лучший способ сделать это.

Я не могу сделать .ThenFetchMany(), поскольку это касается дочерних объектов, но те, которые мне нужны, на том же уровне.

1 Ответ

32 голосов
/ 08 марта 2011

Ну, запрос по-прежнему будет возвращать результаты, которые вы хотите, но, как уже было сказано, он вернет декартово произведение, т.е. запрос SQL вернет count(e.Subordinates) * count(e.Orders) результатов, которые могут сложиться довольно быстро, особенно если у вас больше всего две коллекции.

NHibernate представил Фьючерсы с выпуском 2.1. К сожалению, в текущем выпуске NHibernate 3.0, похоже, нет способа заставить их работать с NHibernate.Linq (session.Query<T>()).

Фьючерсы позволяют вам выполнять несколько запросов за одну поездку к базе данных (до тех пор, пока это поддерживает БД, но большинство из них). В этом случае у вас будут только count(e.Subordinates) + count(e.Orders) результаты, что, очевидно, является минимальным.

Фьючерсы работают с критериями API, HQL, и они должны работать с новым API QueryOver (я еще не проверял это).

NHibernate.Linq имеет Query (). ToFuture () и Query (). ToFutureValue (), но пока я получаю исключения только при их использовании.

Edit:

Я только что снова проверил API Linq, и кажется, что он работает, если вы не используете Fetch. Следующее приведет к трем SQL-запросам, которые выполняются за один прием. Общее количество возвращаемых строк будет равно 1 + количество (подчиненных) + количество (заказов).

int id = 1;

// get the Employee with the id defined above
var employee = repo.Session.Query<Employee>()
    .Where(o => o.Id == id)
    .ToFuture<Employee>();

// get the Subordinates (these are other employees?)
var subordinates = repo.Session.Query<Employee>()
    .Where(o => o.HeadEmployee.Id == id)
    .ToFuture<Employee>();

// get the Orders for the employee
var orders = repo.Session.Query<Order>()
    .Where(o => o.Employee.Id == id)
    .ToFuture<Order>();

// execute all three queries in one roundtrip
var list = employee.ToList();
// get the first (and only) Employee in the list, NHibernate will have populated the Subordinates and Orders
Employee empl = list.FirstOrDefault();

Спасибо, что все равно отметили это как ответ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...