2

I have a following database scheme setup which I can't really change.

User
----
Id    (primary key)
[Some simple properties...]


UserAdditionalData
------------------
Id     (primary key)
[Some simple properties...] 
USERID (foreign key to User)

It's clear that the User table doesn't really have any recollection whether or not it is linked to a UserAdditionalData record, so I don't think I can call this a true one-to-one mapping here since they also don't share a mutually exclusive PK.

However, in practice, I would like to be able to work on a User object and for example check if it has a UserAdditionalData record and if so, access its properties.

I've set up my BDO as such:

public class User
{
    [Some simple properties...] 
    public virtual UserAdditionalData UserAdditionalData { get; set; }
}

public class UserAdditionalData
{
    [Some simple properties...] 
    public virtual User User { get; set; }  /* I have this here, 
                                               but I don't really ever 
                                               have to access it in this 
                                               direction */
}

I've set up my mapping as such:

    public UserMapping()
    {
        Table("USER");
        [Some simple properties...] 
        HasOne(x => x.UserAdditionalData).Cascade.None();
    }


    public UserExtraMapping()
    {
        Table("USER_ADDITIONAL_DATA");
        [Some simple properties...] 
        References(x => x.User, "USERID").Unique();
    }

This all compiles, but I see that my UserExtra object (when accessed via a User object) is always null. I've tried a lot of different ways to go about it, read a lot on implementing this as a one-to-many. However, I'm still not being able to get it to work.

Any help would be much appreciated.

Thanks!

[Small UPDATE]: I only have to query the database, not save to it if that's relevant in any way.

user1211204
  • 119
  • 1
  • 2
  • 9

1 Answers1

1

Based on your small update, I would go with a simplified mapping. We would profit from NHibernate real mapping power, and also optimize the User loading. All that because we do need Read-Only mapping.

Firstly, we should introduce simple int property UserId on the Additional class

// extra class is having an int property containig the foreign key
public class UserAdditionalData
{
    public virtual int UserId { get; set; }
}

// that would be the mapping:
public UserExtraMapping()
{
    ...
    Map(x => x.UserId, "USERID");
}

Now, we will use well optimized mapping for lazy loading many-to-one (I.e. in comparison with one-to-one which loads both ends always, here we will get the reference data only if really needed!)

public UserMapping()
{
    ...
    References(x => x.UserAdditionalData)
          .LazyLoad()
          .PropertyRef(e => e.UserId)
          .Not.Insert()
          .Not.Update()
          ;
}

So, for readonly I would do the best to use many-to-one mapping (References())

see also:

Radim Köhler
  • 122,561
  • 47
  • 239
  • 335