Next up for inspection for mapping-by-code is the <many-to-one> element. It's mapping-by-code equivalent is ManyToOne. Here are its possible options:
ManyToOne(x => x.PropertyName, m =>
// other standard column options
m.Cascade(Cascade.All | Cascade.None | Cascade.Persist | Cascade.Remove);
m.Fetch(FetchKind.Join); // or FetchKind.Select
m.Formula("arbitrary SQL expression");
The first parameter (as almost always) is an lambda expression specifying mapped property in our entity. The second (as almost always) are the mapping options.
Column method (as almost always, again) is to specify database column that keeps the relation value. By default, its name is equal to property name, without any "_id" postfix or something. We can change its name only using the overload with string or we can customize all the options using the second overload. Its possibilities are shown in the post about property mapping - it generally works the same way, so I'll skip it here.
Cascade is used pretty often. Note that mapping-by-code redefined it a bit: save-update option is called Persist and delete is Remove here. This is configured using an flags-type enumerable, so it's easy to combine values. There's also an alternative syntax provided using extension methods:
By now, there's no way to map two features useful for legacy inconsistent databases - property-ref and not-found. Maybe Fabio decided that legacy databases wouldn't be mapped with new mappings?
Fluent NHibernate's equivalent
ManyToOne's equivalent in FNH is References:
References(x => x.PropertyName, "column_name")
.PropertyRef(x => x.PropertyRef)
.Formula("arbitrary SQL expression")
ReadOnly is just a FNH's shortcut for setting both .Not.Insert() and .Not.Update().