I have a database schema where the convention for a foreign key's name is:
ForeignTable.Name + ForeignTable.PrimaryKeyName
So, for a Child
table referencing a Parent
table with a primary key column named Key
, the foreign key will look like ParentKey
.
Is there a way to create this convention in my Fluent NHibernate mapping?
Currently I'm using a ForeignKeyConvention
implementation like this:
public class ForeignKeyNamingConvention : ForeignKeyConvention
{
protected override string GetKeyName(PropertyInfo property, Type type)
{
if (property == null)
{
// Relationship is many-to-many, one-to-many or join.
if (type == null)
throw new ArgumentNullException("type");
return type.Name + "ID";
}
// Relationship is many-to-one.
return property.Name + "ID";
}
}
This works exactly as I want for all types which have "ID" as a primary key. What I would like to do is replace the constant "ID" with the name of the primary key of the type being referenced.
If this isn't currently possible with Fluent NHibernate, I'm happy to accept that answer.
Take a look at conventions and especially at implementing a custom foreign key convention.
UPDATE:
Here's an example. Assuming the following domain:
which needs to be mapped to this schema:
you could use this convention:
and to create the session factory:
If you can get the
Mapping<T>
for a class, you can get the name of its Id column.We can get the Mapping object with a little bit of plumbing.
The constructors of
ClassMap<T>
can passthis
into our collection of Mappers.For
AutoMapping<T>
, we can use Override as follows.For a system wide convention I believe this would serve the purpose best. ( I wasn't sure whether to include the whole text or just a portion here, since I answered it here already)
Here's the solution with links to current Fluent NHibernate & automapping documentation.
The issue (a simple example):
Say you have the simple example (from fluent's wiki) with an Entity and it's Value Objects in a List:
With tables which have e.g.
And a foreign key for shelfid -> Shelf.Id
You would get the error: invalid column name ... shelf_id
Solution:
Add a convention, it can be system wide, or more restricted.
Code example:
Now it will automap the
ShelfId
column to theShelf
property inProduct
.More info
Wiki for Automapping
See more about Fluent NHibernate automapping conventions