2010-09-20 12 views
0

Je reçois l'erreur "Enregistrer les entités transitoires non enregistrées" dans NHibernate. J'ai une racine globale, neighborhood qui contient addresses et person, voici un code pseudo rapide pour expliquer la relation:Enregistrement de plusieurs entités enfants dans NHibernate, à la fois

public class Neighborhood { 
    public virtual int Id { get; set; } 
    public virtual IList<Address> Addresses { get; set; } 
} 

public class Address { 
    public virtual int Id { get; set; } 
    public virtual string Address { get; set; } 
    public virtual Person Person { get; set; } //Assume only one person per address 
} 

public class Person { 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
} 

Dans ma carte de quartier Je:

mapping.HasMany(x => x.Addresses) 
     .Inverse() 
     .KeyColumn("NeighborhoodFk") 
     .Cascade.All() 
     .AsBag(); 

Dans mon code je vais souvent veulent créer un et associer une adresse et personne en même temps:

var address = new Address(); 
var person = new Person(); 

var address.Person = person; 

var neighborhood = neighborhoodRepository.Get(id); 

neighborhood.Add(address); 

neighborhoodRepository.DbContext.BeginTransaction(); 
neighborhoodRepository.SaveOrUpdate(neighborhood); 
neighborhoodRepository.DbContext.CommitTransation(); 

je vais obtenir le « transitoire non enregistré entités "sur l'entité Person car elle est attachée à l'entité transitoire Address.

La seule façon que je peux voir ce problème est de sauver le address d'abord, faire un autre appel à la base de données mise à jour neighborhood après la mise à jour, recherchez le address que je viens d'ajouter, fixer le person puis enregistrez à nouveau.

Y a-t-il quelque chose qui me manque pour rendre cela plus facile? Cela ressemble à un cas d'utilisation commun et je ne veux pas faire un tas de tours à la base de données.

Répondre

5

Assurez-vous que vous définissez l'attribut "Cascade" de votre mappage de l'adresse à la personne pour être "save-update" ou "all". Vous avez la cascade de voisinage à adresse, mais vous n'avez pas déclaré que cette cascade inférieure était présente. Si ce n'est pas le cas, vous obtenez cette erreur non parce qu'une personne est attachée à une adresse transitoire, mais parce que l'adresse fait référence à une personne transitoire. Si cette cascade ne peut pas être créée pour quelque raison que ce soit, enregistrez d'abord la personne, puis enregistrez le voisinage, qui se répercutera sur l'adresse, et l'ORM trouvera la personne référencée dans sa session et définira la référence. Cela PEUT entraîner des «allers-retours» supplémentaires selon que vous laissez NH ou la DB générer des colonnes de numérotation automatique. NHibernate est difficile en ce sens qu'il fera des appels de DB quand il est bon et prêt, et cela peut être après que le graphe d'objet entier soit dans la session de NH, ou juste la personne. De toute façon, il va faire un appel Insert dans la base de données pour chaque objet en cours de persistance, de sorte qu'il fera plusieurs "roundtrips", peu importe ce que le code pour ajouter les éléments à la session ressemble.

+0

J'ai raté la deuxième Cascade All, merci! –

Questions connexes