In working on our web application, I came across an interesting issue with our Fluent NHibernate mapping files. On property mappings where we specified a column name (using the .Column("columnName") property), all of the other attributes that we applied to the property (length, nullability, lazyloading, etc) were ignored. This has been documented in here. I needed to move forward with this, so I wrote a simple extension method to handle our scenario.
This extension method is used in place of the Column("columnName") method call and doesn't replace the other values. Instead, it uses reflection to update the defaultColumn field's name value, just as the Length(), Nullable() and other methods do.
public static PropertyPart ColumnName(this PropertyPart part, string columnName) { const BindingFlags accessor = BindingFlags.NonPublic | BindingFlags.Instance; // retrieve the defaultColumn field property var defaultColumnField = typeof(PropertyPart).GetField("defaultColumn", accessor); // get the current value of the field var defaultColumn = (ColumnMapping)defaultColumnField.GetValue(part); // set the column name as appropriate defaultColumn.Name = columnName; // reset the default column with the applied column name defaultColumnField.SetValue(part, defaultColumn); return part; }
I am still not sure why the Fluent guys decided to update the column name property the way that they did, but this seems to do the trick for us. As a result, I have replaced all Column() calls with ColumnName() calls, to prevent these unexpected behaviors in the future.
One risk with this solution, and it is considerable, is that I am binding to the internals of the PropertyPart class, which is subject to change out from under me.
Now, I just need to make sure I investigate the source before deploying a new build to ensure that this won't break my workaround.
What do you think?