Conventions for ICompositeUserTypes and field overrides
Hi,
We're having some trouble getting NHibernate to automap properties of composite user types. The problem entities look something like:
public class TestClass
{
public int Id {get;set;}
public IUserDateStamp Started {get;set;}
public IUserDateStamp Stopped {get;set;}
}
public interface IUserDateStamp
{
public IUser User {get;}
public int UserId {get;}
public DateTime DateStamp {get;}
}
This has to interop with legacy code and, in places, a legacy database, hence the exposed UserId. IUser is not managed by NHibernate at present. The backing table for TestClass looks like:
CREATE TABLE [dbo].[test_table] (
[id] [int] NOT NULL PRIMARY KEY,
[startedDate] [datetime] NOT NULL,
[startedBy] [int] NOT NULL,
[stoppedDate] [datetime] NULL,
[stoppedBy] [int] NULL,
[timestamp] timestamp
)
IUserDateStamps should map to pairs of fields in their containing entity's backing table.
The concrete implementation of IUserDateStamp is nontrivial, so we can't use a Component to map it. We have a UserDateStampUserType class implementing ICompositeUserType to handle conversion of a pair of fields to a complete UserDateStamp instance and back again, which exposes 'UserId' and 'DateStamp' as PropertyNames.
Firstly, is there any way to get Fluent NHibernate to automap properties of type IUserDateStamp to use UserDateStampUserType? Left to its own devices it creates many-to-one mappings for these properties and then complains that there is no known IUserDateStamp entity. IPropertyConventions never get called for these mappings, so the examples for IUserType and UserTypeConvention do not seem to apply.
Specifying explicit CustomType overrides causes NHibernate to map them as properties backed by two columns, but then they both reference 'UserId' and 'DateStamp' fields. This is fixed by:
mapping.Map(m => m.Started).CustomType<UserDateStampUserType>().Columns.Clear().Columns.Add("startedBy", "startedDate");
But using overrides for this is rather clumsy, as we have many properties like these throughout the object model.
So secondly, is there a way to define conventions for overriding these field mappings?
Thanks,
Alex
2 Posted by Alex Davidson on 24 Aug, 2010 09:03 AM
Fixed automapping this type with an IUserTypeConvention after all. No idea why it didn't work the first time.
Column names were a little trickier, since Fluent NHibernate provides no write access to those through IPropertyInstance (at least, not for composite types). I wrote the following base class for mapping composite types:
Horrible, fragile reflection, but works nicely :)
3 Posted by Prashanth on 02 Dec, 2010 07:29 PM
Hi, my problem is similar to the above so can you please send me the code for the UserDateStampUserType class implementing ICompositeUserType.
-- Thanks
4 Posted by Steve Powell on 01 Feb, 2011 11:50 AM
Thanks Alex. That worked a treat!