How do I map a table join in NHibernate / Fluent NHibernate that uses a unique key instead of the primary key?

3,047 views
Skip to first unread message

Dylan Beattie

unread,
Jun 2, 2011, 7:48:11 AM6/2/11
to fluent-n...@googlegroups.com

Hello all,

(this is cross-posted to the list and StackOverflow - http://stackoverflow.com/questions/6213658/ - is that OK? Shout if it's not and I won't do it again!)

I have these tables in my SQL Server database. MemberCv is a legacy table that we can't modify, so we're using an NHibernate join mapping to map the extra columns we need for a new feature:

MemberCv (
   
MemberId varchar -- part of composite key,
   
PublicationCode int -- part of composite key,
   
PictureFileName varchar -- UNIQUE KEY constraint UK_PictureFileName
)

PhotoSTatus (
   
FileName varchar -- primary key,
   
IsHidden bit,
   
Sequence int
)

and so the resulting C# class will look like:

public class MemberCv {
   
public Member Member { get; set; }
   
public Publication Publication { get; set; }
   
public string FileName { get; set; }
   
public int IsHidden { get; set; }
   
public int Sequence { get; set; }
}

The problem is, NHibernate (using Fluent NH) is trying to map it using the primary (composite) key that's defined on the MemberCv table. Yes, I know NHibernate hates primary keys. No, I can't introduce an artificial key and turn the existing one into a unique constraint.

In the MemberCv override map, we have tried:

map.Join("PhotoStatus", join
 
.KeyColumn("FileName")
 
.References(cv => cv.PictureFileName)
 
.UniqueKey("UK_PictureRef");

which results in:

NHibernate.FKUnmatchingColumnsException : Foreign key (FK3F10D2B7EA4868D8:MyDatabase.dbo.PhotoStatus [FileName])) must have same number of columns as the referenced primary key (MemberCv[Member, Publication])

We've even tried using computed columns in the PhotoStatus table (Filename is based on MemberId and PublicationCode, so it's possible to compute the elements of the associated composite key) and then using implicit joining, which results in:

NHibernate.FKUnmatchingColumnsException : Foreign key (FK3F10D2B7F670FD07:MyDatabase.dbo.PhotoStatus [MemberCv_id])) must have same number of columns as the referenced primary key (MemberCv[Member, Publication])

Any ideas? This is one of those scenarios that should be quite easy but we just can't find the right configuration for it...

James Gregory

unread,
Jun 2, 2011, 8:20:23 AM6/2/11
to fluent-n...@googlegroups.com
I'll do some digging.

In the meantime, do you need to insert into this table? (please say no). If not, you could use a view to get around the problem. I'll try find a proper solution.

Dylan Beattie

unread,
Jun 2, 2011, 8:26:50 AM6/2/11
to fluent-n...@googlegroups.com
I'm afraid we need to update and insert PhotoStatus rows - we're using NH to provide a sane domain model over a criminally twisted DB schema and apart from this little edge detail, so far it's going rather well...

The alternative is to map PhotoStatus as a component or associated entity and then manage the abstraction in our own code, but a join mapping would be far cleaner and consistent with what we've done elsewhere.

Thanks,

-D-

On 2 June 2011 13:20, James Gregory <jagregory.com@gmail.com> wrote:
I'll do some digging.

In the meantime, do you need to insert into this table? (please say no). If not, you could use a view to get around the problem. I'll try find a proper solution.

--
You received this message because you are subscribed to the Google Groups "Fluent NHibernate" group.
To view this discussion on the web visit https://groups.google.com/d/msg/fluent-nhibernate/-/ZnlGOFRTeHFDN29K.
To post to this group, send email to fluent-n...@googlegroups.com.
To unsubscribe from this group, send email to fluent-nhibern...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/fluent-nhibernate?hl=en.

James Gregory

unread,
Jun 2, 2011, 8:37:49 AM6/2/11
to fluent-n...@googlegroups.com
Bad news, I'm afraid.

In theory, you should be able to put a property-ref attribute on the key in the join and point that to the property in your MemberCv table (I'm not certain we actually expose that in FNH, probably for the following reason...); however, it would be ignored because of a bug in NH: NH-1452

I've just done a test, and NH just flat-out ignores the property-ref when used in a join.

An alternative, as you said, would be to use a component or many-to-one; you could use a private field and have the properties just delegate. Not nice, but I don't see any other option until that bug gets fixed.
Reply all
Reply to author
Forward
0 new messages