2010-11-09 8 views
1

I ont les classes suivantescommande de mise à jour non désiré NHibernate

public class Contact 
{ 
    public Contact() { 
     Addresses = new List<Address>(); 
     EmailAddresses = new List<EmailAddress>(); 
     PhoneNumbers = new List<PhoneNumber>(); 
    } 
    public virtual int ContactID { get; private set; } 
    public virtual Firm Firm { get; set; } 
    public virtual ContactType ContactType { get; set; } 
    public virtual string FullName { get; set; } 
    public virtual string FiscalCode { get; set; } 
    public virtual string Notes { get; set; } 
    public virtual ContactRole ContactRole { get; set; } 

    public virtual IList<Address> Addresses { get; private set; } 
    public virtual IList<EmailAddress> EmailAddresses { get; private set; } 
    public virtual IList<PhoneNumber> PhoneNumbers { get; private set; } 
} 

public class Address 
{ 
    public virtual int AddressID { get; private set; } 
    public virtual string StreetAddress { get; set; } 
    public virtual string ZipCode { get; set; } 
    public virtual string City { get; set; } 
    public virtual Province Province { get; set; } 
    public virtual Country Country { get; set; } 
    public virtual Contact Contact { get; set; } 
    public virtual AddressType AddressType { get; set; } 
    public virtual bool PostalAddress { get; set; } 
} 

Ces classes ont été mis en correspondance avec la base de données en utilisant FluentNHibernate. Ce sont les classes de mappage

public ContactMap() { 
    Table("Contacts"); 
    Id(c => c.ContactID).Column("ContactID").GeneratedBy.Identity(); 
    References(c => c.Firm).Column("FirmID"); 
    References(c => c.ContactType).Column("ContactTypeID"); 
    Map(c => c.FullName); 
    Map(c => c.FiscalCode); 
    Map(c => c.Notes); 
    References(c => c.ContactRole).Column("ContactRoleID"); 
    HasMany(c => c.Addresses).Cascade.SaveUpdate(); 
    HasMany(c => c.EmailAddresses).Cascade.SaveUpdate(); 
    HasMany(c => c.PhoneNumbers).Cascade.SaveUpdate(); 
} 


public AddressMap() { 
    Table("Addresses"); 
    Id(a => a.AddressID).Column("AddressID").GeneratedBy.Identity(); 
    Map(a => a.StreetAddress); 
    Map(a => a.ZipCode); 
    Map(a => a.City); 
    References(a => a.Province).Column("ProvinceID"); 
    References(a => a.Country).Column("CountryID"); 
    References(a => a.Contact).Column("ContactID"); 
    References(a => a.AddressType).Column("AddressTypeID"); 
    Map(a => a.PostalAddress); 
} 

J'essaie de charger une quantité considérable de contacts dans la base de données en utilisant ces classes. Mon code qui créent ces objets peut être logiquement expliqué que suivre

Create a contact 
For each address of this contact 
    create an address 
    set the contact address 
    add the address to the contact collection 
Next 
For each email of this contact 
    create an email 
    set the contact email 
    add the email to the contact collection 
Next 

Je n'ai aucun problème avec toute la collection descendant comme le courrier électronique, PhoneNumber sauf que j'ai un problème avec adresse. En fait, lorsque je tente d'insérer un contact qui a au moins une adresse que je reçois l'erreur suivante

Could not insert collection: [GSLConverter.Entities.Contact.Addresses#3551][SQL: UPDATE Addresses SET AuthorID = @p0 WHERE AddressID = @p1] 
Invalid column name 'AuthorID' 

Au lieu d'utiliser ContactID utilise AuthorID. D'où vient cet AuthorID ????

Ce sont les requêtes qui NHibernate Executer sur le serveur

INSERT INTO Addresses (StreetAddress, ZipCode, City, PostalAddress, ProvinceID, CountryID, ContactID, AddressTypeID) VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7); 
select SCOPE_IDENTITY(); 
@p0 = 'xxx xxxxxx, 69 ', @p1 = '80142', @p2 = 'xxxxxx', @p3 = False, @p4 = 1, @p5 = 113, @p6 = 3632, @p7 = 1 

UPDATE Addresses SET AuthorID = @p0 WHERE AddressID = @p1; 
@p0 = 3632, @p1 = 26 

@Stefan Steinegger: c'est la cartographie de la classe, la seule, qui font référence à un membre AuthorID

public IssueNoteMap() { 
    Table("IssueNotes"); 
    Id(ino => ino.IssueNoteID).Column("IssueNoteID").GeneratedBy.Identity(); 
    References(ino => ino.Issue).Column("IssueID"); 
    Map(ino => ino.NoteDate); 
    Map(ino => ino.NoteTitle); 
    Map(ino => ino.NoteBody); 
    References(ino => ino.Author).Column("AuthorID"); 
} 

Le champ AuthorID est une référence à la table Contact qui n'a pas encore été mappée sur le côté Contact (comme vous pouvez le voir dans le mappage de contacts précédent

+0

Est-il possible que vous avez certaines conventions ailleurs qui pourraient interférer? Cela semble ridicule de demander, mais avez-vous un objet auteur qui fait référence à Address? Il est possible que s'il y a, une cascade pourrait déclencher quelque chose d'inattendu en raison de la liaison. – ddango

+0

Bonjour, merci pour votre réponse. Je n'ai aucune convention expressément configurée. J'ai fait une recherche sur mes classes et en fait j'ai trouvé un champ AuthorID dans une classe qui n'est, en aucune façon, lié à l'adresse et au contact. Est-il possible d'afficher le mappage effectué par FluentNHibernate sur les classes? – Lorenzo

+0

A quoi ressemble ce mappage avec l'AuthorId? –

Répondre

5

Est-ce que IssueNote.Author par hasard un type de Contact? Si oui, la Fluent Mapping de

References(ino => ino.Author).Column("AuthorID"); 

tente de mettre à jour votre table « Adresses » pour veiller à ce qu'il a également le ContactId stocké dans la clé étrangère de AuthorId que vous avez dit que ce que IssueNote.Author utilise pour la cartographie de Contact s

vous avez dit NHibernate ceci:

alt text

Lorsque vous voulez vraiment ceci: alt text

, modifiez le IssueNoteMap à ce qui suit afin que le contactID est utilisé pour cartographier l'auteur et il devrait fonctionner

References(ino => ino.Author).Column("ContactId"); 
+0

Wow !!! Vous avez tout à fait raison! Je viens de commencer à travailler avec NHibernate et, comme je suis trop paresseux quand il s'agit de lire des manuels, j'ai supposé que le mapping 'References' se réfèrerait à la colonne side locale. J'ai appliqué votre suggestion et tout fonctionne. Merci beaucoup. Encore une question: comment avez-vous fait ces diagrammes? Je veux dire, quel outil avez-vous utilisé? Merci encore – Lorenzo

+1

Pas de soucis :) Les diagrammes proviennent de l'excellent site http://yuml.me/ – ChrisAnnODell

Questions connexes