2
votes

Im just trying to work out if its possible to map a 1 - 0..1 (one to at most one \ one to zero or one) relationship using fluent NHibernate without the use of a Private Collection. An example of the class structure is below:

    public class ClassA
    {
        public int ClassAId { get; set; }

        public string SomeDetails { get; set; }

        public ClassB ClassB { get; set; }

    }

    public class ClassB
    {
        public ClassA ClassA { get; set; }

        public int ClassBId { get; set; }

        public string SomeChildDetails { get; set; }
    }

In this example, ClassA can have a ClassB, or ClassB can be null.

The DB structure would look something like:

   ClassA Table
   -------------
   int ClassA_ID  PK
   string SomeDetails

   ClassB Table
   ------------
   int ClassA_Id   PK  FK
   string SomeChildDetails

In this situation, you cannot use HasOne(x => x.ClassB).Cascade.All(); as this assumes it must always have one.

Is there a way to do this without having a one to many relationship with a private IList on ClassA and having the getter of the ClassB property getting the first entry in the list.

Ta

R

1
Can't you just set the Id to be int??Oskar Kjellin

1 Answers

3
votes

Apart from marking all your properties on mappings as virtual, References should do the trick:

References(x => x.ClassB).Nullable().Cascade.All();

The Fluent NHibernate's documentation says it's the equivalent of many-to-one relationship, but works with single properties too, which ends up being 1-0..1 relationship. You could try the HasOne with Nullable() modifier, but it says in the docs that you generally should use References instead.

[EDIT to the comment]:

As far as I remember, the default foreign key naming policy for NHibernate is keyname_id, which you can either change by implementing you own ForeignKeyConvention (this one is for all mappings). Let's say your foreign key policy is TableNameID, which would be 'ClassBID':

internal class MyFkeyConvention : ForeignKeyConvention
{
    protected override string GetKeyName(FluentNHibernate.Member property, Type type)
    {
        if(property != null)
            return property.Name + "ID";
        return type.Name + "ID";
    }
}

or just use this one if you need it only in one place:

References(x => x.ClassB).Column("YourForeignKeyColumnName").Nullable().Cascade.All();