0

I have done some search on StackOverflow and google in general and I am still having trouble finding out why this is happening and how to fix it. I am new to NHibernate and FluentNHibernate, so please be gentle :)

While doing some intergration tests, I found that if I was to just modify the Seller's Name, NHibernate would generate update scripts for all the Contacts and the Login as well, and delete all the reference in Contact_Seller and readd them.

I feel like I should do something like Inverse() in my maps, but I do not know how since Contact and Login do not have references to Sellers or Buyers in my object model.

Here is my setup (Objects, Maps, and Database). Let me know if you need more info, and thanks.

class Buyer{
    public int BuyerID {get;set;}
    public Login Login {get;set;}
    public IList<Contact> Contacts  {get;set;}
    ... Other Buyer properties ...

}
class Seller{
    public int SellerID {get;set;}  
    public Login Login {get;set;}
    public IList<Contact> Contacts  {get;set;}
    public string Name {get;set;}
    ... Other Seller properties ...
}
class Login{
    public int LoginID {get;set;}
    public string Username {get;set;}
    public byte[] Password {get;set;}
    public string Email {get;set;}
}
class Contact{
    public int ContactID {get;set;}
    ... Contact Info...
}

public BuyerMap()
{    
    Id(x => x.BuyerID);

    ... Other Seller properties ...

    HasManyToMany(x => x.Contacts).Table("Contact_Buyer").Cascade.All();            
    References(x => x.Login).Cascade.All();

}

public SellerMap()
{    
    Id(x => x.SellerID);

    ... Other Seller properties ...

    HasManyToMany(x => x.Contacts).Table("Contact_Seller").Cascade.All();           
    References(x => x.Login).Cascade.All();

}
public LoginMap()
    {
        Id(x => x.LoginID);

        Map(x => x.Username);
        Map(x => x.Password);
        Map(x => x.Email);

    }

public ContactMap()
{
    Id(x => x.ContactID);

        ... Other Contact properties ...        

}

TABLE Buyer(
    [BuyerID] [int] IDENTITY(1,1) NOT NULL, 
    [LoginID] [int] NULL,
    ... Other Buyer fields ...
    )


TABLE Seller(
    [SellerID] [int] IDENTITY(1,1) NOT NULL,    
    [LoginID] [int] NOT NULL,
    [Name]     [varchar] NOT NULL,
    ... Other Seller fields ...
    )

TABLE Login(
    [LoginID] [int] IDENTITY(1,1) NOT NULL,     
    ... Other Login fields ...
    )

TABLE Contact(
    [ContactID] [int] IDENTITY(1,1) NOT NULL,   
    ... Other Contact fields ...
    )

TABLE Contact_Seller(
    [ContactID] [int] NOT NULL, 
    [SellerID]  [int] NOT NULL, 
    )

TABLE Contact_Buyer(
    [ContactID] [int] NOT NULL, 
    [BuyerID]  [int] NOT NULL,  
    )
Phillip
  • 229
  • 2
  • 14

1 Answers1

1

looking at the mappings you are not interested in the Order of Contacts but i assume they should be unique. So change the Contacts collection to ICollection<Contact> and

HasManyToMany(x => x.Contacts).AsSet();

the NHibernate can optimise some access since it knows that the link table contains unique pairs.

Firo
  • 30,626
  • 4
  • 55
  • 94
  • Good points (just did some research on the AsSet()) If I change my contact collections to ICollection, do I still require the AsSet()? Or will it see the ICollection and use it's reflection magic? I will try this out! Thanks – Phillip Oct 23 '12 at 14:58
  • NHibernate will assume ICollection as Bag Iesi.Collections.Generic.ISet will automaticly be AsSet() – Firo Oct 23 '12 at 18:11
  • I have not forgotten! I tested this out today, and it cause some tests to fail. In particular, if I create a new Seller, add several new contacts (all with ID=0), it will only keep the first contact. I think when it casts to the set, it removes all but one contact, since they all have the same ID. Is this normal? – Phillip Oct 30 '12 at 17:50
  • set means unique items, if tests are failing then the equals implementation is not correct. Try `var other = obj as Entity; return Id == 0 ? ReferenceEqual(this, other) : Id == other.Id;` – Firo Oct 31 '12 at 18:47
  • You are correct, I added the condition for ID==0 but I did not know about the ReferenceEquals. Again thanks! – Phillip Nov 01 '12 at 19:55