Many moons ago, when Fluent NHibernate first started, the conventions were different. They were inline and very specific in their purpose. Some say it was better that way, and we've heard your criticism and chose to ignore it for now. If you're not just complaining that things were better in your day, then you can learn how to convert your old conventions into the new style here.
It goes without saying that implementing interfaces is going to be more verbose than using in-line lambdas, so prepare yourself because these conversions are going to end up being longer; however, the added separation makes for a much less coupled design. I hope you learn to love it, and if not, we accept patches.
I'd advise that you read about the conventions first, and the available conventions, once you understand how the new conventions work you can use this page to help migrate any existing ones.
Replacing existing conventions
Below are all the original conventions (or near enough) with the equivalent interface or base-class you need to use.
I'll show some examples of updating your conventions after the table.
Old style | New style |
---|---|
ITypeConvention | IClassConvention |
IPropertyConvention | Same but different signature |
Conventions.GetTableName | IClassConvention or a convention shortcut |
Conventions.GetPrimaryKeyName and Conventions.GetPrimaryKeyNameFromType | IIdConvention or a convention shortcut |
Conventions.GetForeignKeyName | ForeignKeyConvention base-class, or the specific relationship interface you need (IHasManyConvention for example). |
Conventions.GetReadOnlyCollectionBackingFieldName | ICollectionConvention |
Conventions.IdConvention | IIdConvention |
Conventions.OneToManyConvention | IHasManyConvention |
Conventions.ManyToOneConvention | IReferenceConvention |
Conventions.OneToOneConvention | IHasOneConvention |
Conventions.GetManyToManyTableName | ManyToManyTableNameConvention base-class |
Conventions.JoinConvention | IJoinConvention |
Conventions.DefaultCache | IClassConvention or a convention shortcut |
Conventions.GetVersionColumnName | IVersionConvention |
Conventions.DefaultLazyLoad | IClassConvention or a convention shortcut |
Conventions.DynamicUpdate | IClassConvention or a convention shortcut |
Conventions.DynamicInsert | IClassConvention or a convention shortcut |
Conventions.GetComponentColumnPrefix | IComponentConvention |
Primary Key naming
You used to write the following to override the primary key naming to be TableNameId:
.WithConvention(c =>
c.GetPrimaryKeyName = type => type.Name + "Id");
Now you'd implement an IIdConvention which allows you to alter the actual Id mapping itself.
public class PrimaryKeyNamingConvention
: IIdConvention
{
public void Apply(IIdentityInstance instance)
{
id.Column(id.EntityType.Name + "Id");
}
}
That's your new convention, which you'd situate with all your other conventions, then use either of the following snippets to hook them in:
.Conventions.AddFromAssemblyOf<PrimaryKeyNamingConvention>();
.Conventions.Add<PrimaryKeyNamingConvention>();
Many-to-many table naming
See: ManyToManyTableNameConvention
You used to write the following to override the table name used for many-to-many relationships:
.WithConvention(c =>
c.GetManyToManyTableName = (child, parent) => child.Name + "To" + parent.Name);
Now you'd derive from the ManyToManyTableNameConvention which already has all the logic created for setting the other side of bi-directional relationships, and knows not to overwrite the table names if one already is set.
public class CustomManyToManyTableNameConvention
: ManyToManyTableNameConvention
{
protected override string GetBiDirectionalTableName(IManyToManyCollectionInspector collection, IManyToManyCollectionInspector otherSide)
{
return collection.EntityType.Name + "To" + otherSide.EntityType.Name;
}
protected override string GetUniDirectionalTableName(IManyToManyCollectionInspector collection)
{
return collection.EntityType.Name + "To" + collection.ChildType.Name;
}
}
That's your new convention, which you'd situate with all your other conventions, then use either of the following snippets to hook them in:
.Conventions.AddFromAssemblyOf<ManyToManyTableNameConvention>();
.Conventions.Add<ManyToManyTableNameConvention>();
Automapping
If you're using automapping, the conventions used to be mixed up together with the configuration options. Now anything that can be thought of configuring the automapper's discovery capabilities (for example IsBaseType
) is now available only under the Setup
method (which in-part replaces WithConvention
), everything else is a standard convention and is handled through the Conventions
property like the regular conventions.
// old
.WithConvention(c =>
c.IsBaseType = type => type == typeof(BaseEntity));
// new
.Setup(s =>
s.IsBaseType = type => type == typeof(BaseEntity))
Attribute based conventions
If you were using the ForAttribute<T>
method, then you can inherit from the AttributePropertyConvention base-class.