I am spending quite a lot of time recently with NHibernate 3.2 mapping-by-code feature and as I've already mentioned, my most serious obstacle with this evaluation is that there is virtually no resources on the net. If these answers are everything the Web has to offer, there's a lot of space for improvement.
I am planning to prepare a series of posts covering the most important NHibernate's mapping features implemented using mapping-by-code. I'll probably follow Ayende's great series about XML mappings, at least in terms of ordering. I'm not going to describe the features itself, I'll rather focus on mapping interface. For features description - refer to Ayende's posts.
So let's start with <property>. Its equivalent in mapping-by-code is... Property - isn't it surprising? Well, in Fluent NHibernate it is called Map. There's no rocket science here and everything is pretty simple.
Property(x => x.Property, m =>
{
m.Column("columnName");
// or
m.Column(c =>
{
c.Name("columnName");
c.Default("defaultValue");
c.SqlType("varchar(max)");
c.Length(SqlClientDriver.MaxSizeForLengthLimitedString + 1);
c.NotNullable(true);
c.Check("len(columnName) > 1");
c.Precision(2);
c.Scale(2);
c.Index("column_idx");
c.Unique(true);
c.UniqueKey("column_uniq");
});
m.Type<string>(); // or IUserType
m.Update(true);
m.Insert(true);
m.Formula("arbitrary SQL expression");
m.Access(Accessor.Field); // or Accessor.Property or Accessor.NoSetter
// or
m.Access(typeof(CustomAccessor));
m.OptimisticLock(false);
m.Generated(PropertyGeneration.Insert); // or PropertyGeneration.Always or PropertyGeneration.Never
m.Lazy(true);
});
Mapped property goes as lambda expression (or string property name, if it is hidden) in first parameter and this is the only obligatory element - everything else has its defaults and can be skipped (and most often, it should). All the other attributes from the XML have its corresponding method in configuration object in second parameter.
One thing to note is that column can be configured using Column method either with simple string (when customising only name) or with column configuration, that allows to set different DDL-level column properties. Not every feature is implemented in every provider and not every feature makes sense for every column type obviously - i.e. Precision and Scale are for numerics only.
Side note: In the example above I'm specifying SqlType explicitly to varchar(max), but this line
Property(x => x.Name, m => m.Length(SqlClientDriver.MaxSizeForLengthLimitedString + 1));
will also produce varchar(max) in SQL Server, and that solution seems to be nicer.
Fluent NHibernate's equivalent
Map(x => x.Property, "columnName")
.Default("defaultValue")
.CustomSqlType("varchar(max)")
.Length(SqlClientDriver.MaxSizeForLengthLimitedString + 1)
.Not.Nullable()
.Check("len(columnName) > 1")
.Precision(2)
.Scale(2)
.Index("column_idx")
.Unique()
.UniqueKey("column_uniq")
.CustomType<string>()
.Update()
.Insert()
.Formula("arbitrary SQL expression")
.Access.Field()
// or .Access.Using<CustomAccessor>()
.OptimisticLock()
.Generated.Insert()
.LazyLoad()
.ReadOnly();
The only difference apart from different naming for some properties and Property vs. Map name itself is the ReadOnly method available in FNH. It is just a shortcut for setting both .Not.Insert() and .Not.Update().
well done
ReplyDeletegood job
ReplyDelete