2010-05-12 3 views
4

J'ai quelques objets:NHibernate - désireux lecture d'une liste avec des listes d'enfants déjà peuplées

Public Class Person() { 
    public int Id {get;set;} 
    public IList<Account> Accounts {get;set;} 
    public string Email {get; set;} 
} 

public class Account(){ 
    public int Id {get;set;} 
    public IList<AccountPayment> Payments {get;set;} 
    public IList<Venue> Venues {get;set;} 
} 

public class AccountPayment(){ 
    public int Id {get;set;} 
    public DateTime PaymentDate {get;set;} 
    public decimal PaymentAmount {get;set;} 
} 

public class Venue(){ 
    public int Id {get;set;} 
    public string AddressLine1 {get;set;} 
    public string Postcode {get;set;} 
} 

Ces classes sont mises en correspondance avec MS Sql NHibernate - il y a une table dans la db par classe ...

Je veux créer une méthode dans mon dépôt, GetAccounts (int PersonID), qui retournera une liste avec toutes les collections enfants du compte remplies de la manière la plus efficace. Quelqu'un peut-il me donner des indications sur la façon de faire cela? Je ne veux pas vraiment mettre en place les listes comme sous-sélection dans mes mappings si je peux l'aider ...

Merci.

+0

Ce blog explique un moyen efficace de le faire: http://ayende.com/Blog/archive/2010/01/16/eagerly-loading-entity-associations-efficiently -with-nhibernate.aspx –

+0

Salut Diego, Le problème est que j'essaie de charger avec impatience les collections enfants, de l'objet Propriété de l'objet Personne - J'ai déjà regardé cet article en essayant de le faire, et lors d'une seconde enquête, Je ne peux toujours pas voir un moyen de le faire. Est-ce que je manque quelque chose? – Paul

+0

Ce lien ne fonctionne plus, et malheureusement la réponse ne contient aucune des informations pertinentes. – Aaronaught

Répondre

0

Ok, après avoir essayé de le faire de différentes façons, j'ai finalement trouvé que la solution la plus efficace pour moi a exposé à cette question:

Eager loading child collection with NHibernate

Ma question était au-dessus une version très simplifiée du vrai défi que j'avais, mais en utilisant la méthode ci-dessus, j'ai réussi à faire baisser le db à 2 ... une énorme amélioration par rapport à ma mise en œuvre initiale.

Merci pour votre aide et les pointeurs les gars. Appris un peu en cours de route ...

1

Si vous avez mappé vos classes aux tables de la façon dont vous le mentionnez, pourquoi n'appelez-vous pas simplement l'objet Personne pour obtenir tous leurs comptes? Lorsque vous appelez l'objet Personne de votre référentiel, vous pouvez charger les comptes. Comme si:

public Person GetById(int id) 
    { 
     using (var tx = _sessionBuilder.GetSession().BeginTransaction()) 
     { 
      // -- Lazy load way -- 
      //Person person = _sessionBuilder.GetSession().Get<Person>(id); 
      //tx.Commit(); 
      //return person; 

      // -- Eager load way --     
      Person person = _sessionBuilder.GetSession().CreateCriteria<Person>() 
        .Add(Restrictions.IdEq(id)) 
        .SetFetchMode("Accounts", FetchMode.Eager) 
        .UniqueResult<Person>(); 
      tx.Commit(); 
      return person; 
     } 
    } 
+0

Idéalement, je voudrais charger les collections sur la propriété Accounts de l'objet person (Account payment et Venue). Je ne pense pas que ce qui précède peut y parvenir? – Paul

+0

SetFetchMode pour les collections (surtout lorsqu'il y en a plus d'une) ce n'est pas une bonne idée en termes de performances. –

+0

@Paul - Je ne suis pas sûr que FetchMode.Eager fasse des collections imbriquées. Vous pouvez utiliser NHProf pour voir le SQL. Une autre façon de charger avec impatience peut être d'appeler votre dépôt dans votre déclaration d'origine et d'appeler les paiements et les sites avec impatience. .... .SetFetchMode ("paiements", FetchMode.Eager) .SetFetchMode ("Lieux", FetchMode.Eager) .... – LordHits

Questions connexes