Стремительно получить несколько свойств коллекции (используя QueryOver / Linq)? - PullRequest
35 голосов
/ 28 апреля 2011

Я нашел 2 похожих вопроса:

Согласно этой странице :

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

var employees = session.Query<Employee>()
    .Fetch(e => e.Subordinates)
    .Fetch(e => e.Orders).ToList();

Выполняет декартово произведение против базы данных, поэтому общее количество возвращенных строк будет общее число подчиненных заказы.

Допустим, у меня есть следующая модель:

public class Person
{
    public virtual int Id { get; private set; }
    public virtual ICollection<Book> Books { get; set; }
    public virtual ICollection<Article> Articles { get; set; }
    public virtual ICollection<Address> Addresses { get; set; }
}

Какой самый простой способ загружать всех людей своими книгами, статьями и адресами с помощью QueryOver / Linq (без возврата декартового произведения)?

Спасибо


Обновление:

См. cremor ответ ниже и Florian Lim * ответ в этой теме . Следующий код работает хорошо, только одна поездка в базу данных.

var persons = session.QueryOver<Person>()
    .Future<Person>();
var persons2 = session.QueryOver<Person>()
    .Fetch(x => x.Books).Eager
    .Future<Person>();
var persons3 = session.QueryOver<Person>()
    .Fetch(x => x.Articles).Eager
    .Future<Person>();
var persons4 = session.QueryOver<Person>()
    .Fetch(x => x.Addresses).Eager
    .Future<Person>();

Ответы [ 2 ]

1 голос
/ 16 декабря 2016

Я предпочитаю использовать поставщика linq, если это вообще возможно, особенно если вы используете более новые версии nhibernate (> = 4.0).Пока ваши коллекции отображаются как ISets (требуется .net framework> = 4), которые мы конвертировали в такие, чтобы мы могли загружать их и избегать декартовых продуктов.Я чувствую, что это не то, что широко рекламируется, но я предпочитаю этот метод, где это применимо, чем что-либо еще:

public class Person
{
    public virtual int Id { get; private set; }
    public virtual ISet<Book> Books { get; set; }
    public virtual ISet<Article> Articles { get; set; }
    public virtual ISet<Address> Addresses { get; set; }
}

public Person()
{
    this.Books = new HashSet<Book>();
    this.Articles = new HashSet<Article>();
    this.Addresses = new HashSet<Address>();
}

Если у вас есть коллекции, определенные как выше, то вы можете сделать следующее и все же избежатьпроблемы декартовых произведений:

var persons = session.Query<Person>()
                     .FetchMany(x => x.Books)
                     .FetchMany(x => x.Articles)
                     .FetchMany(x => x.Addresses)
                     .ToList();
0 голосов
/ 03 августа 2016
public IList<Person> GetAll()
{
    var persons = session.QueryOver<Person>()
        .Future<Person>();

    session.QueryOver<Person>()
        .Fetch(x => x.Books).Eager
        .Future<Person>();

    session.QueryOver<Person>()
        .Fetch(x => x.Articles).Eager
        .Future<Person>();

    session.QueryOver<Person>()
        .Fetch(x => x.Addresses).Eager
        .Future<Person>();

    return persons.ToList();
}
...