Fluent nHibernate: one-to-many relationship Issue

2019-01-23 21:42发布

问题:

I have a problem with one-to-many relationships. I have the following domain classes:

public class Installation : Entity<Installation>
{        
    public virtual string Name { get; set; }
    public virtual IList<Institution> Institutions { get; set; }

    public Installation()
    {
        Institutions = new List<Institution>();
    }
}
public class Institution : Entity
{
    public virtual string Name { get; set; }
    public virtual string Address { get; set; }
    public virtual string City { get; set; }
    public virtual Installation Installation { get; set; }        
}

I have made the Entity base class according to the following post. I have the following mappings defined:

public class InstitutionMapping : ClassMap<Institution> 
{
    public InstitutionMapping()
    {
        WithTable("Institution");
        Id(i => i.Id).GeneratedBy.Guid();
        Map(i => i.Name).Not.Nullable().WithLengthOf(50);
        Map(i => i.Address).Not.Nullable().WithLengthOf(50);
        Map(i => i.City).Not.Nullable().WithLengthOf(50);
        References(i => i.Installation).ColumnName("InstallationId").Not.Nullable().WithForeignKey();
    }
}

public class InstallationMapping : ClassMap<Installation>
{
    public InstallationMapping()
    {
        WithTable("Installation");
        Id(i => i.Id).GeneratedBy.Guid();
        Map(i => i.Name).Not.Nullable().WithLengthOf(50);
        HasMany<Institution>(i => i.Institutions).KeyColumnNames.Add("InstallationId").Inverse().Cascade.All();
    }
}

I unit test adding institutions to an installation in the following way:

Installation installation = TestHelper.CreateAnonymousInstallation();
installation.Institutions.Add(TestHelper.CreateAnonymousInstitution());
installation.Institutions.Add(TestHelper.CreateAnonymousInstitution());
session.Save(installation);    
session.Flush();
session.Clear();
Installation returnedInstallation = session.Get<Installation>(installation.Id);
Assert.AreEqual(2, returnedInstallation.Institutions.Count);

I get an assertion exception because the returned number of institutions is 0. I have checked in the SQL Profiler and the institutions are saved in the database but their InstallationId is null. Could somebody tell me what I am doing wrong?

回答1:

When you have a persistent collection with inverse="false", then the parent object owns the relationship and any changes to the parent's collection will be reflected in the database.

When you have a persistent collection with inverse="true", then the child object owns the relationship and any changes to the child's reference to the parent will be reflected in the database.

Because you set inverse="true", you will need to change the child object's reference to the parent object in order for NHibernate to pick up on it. If you wish NHibernate to pick up on the changes to the relationship whenever you add children to or remove children from the parent's collection, you must set inverse="false" on the collection.



回答2:

You have to manually set the Installation Property of an Institution, specifically,

Installation installation = TestHelper.CreateAnonymousInstallation();
Institution institution = TestHelper.CreateAnonymousInstitution();
institution.Installation = installation;
installation.Institutions.Add(institution);