36

私は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回答を参照してください。次のコードはうまく機能します。データベースへのラウンドトリップは 1 回だけです。

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>();
4

2 に答える 2

5

特に新しいバージョンの nhibernate (>= 4.0) を使用している場合は、可能であれば linq プロバイダーを使用することをお勧めします。コレクションが ISets (.net フレームワーク >= 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();
于 2016-12-16T13:22:38.577 に答える
-2
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();
}
于 2016-08-03T03:14:44.377 に答える