views:

334

answers:

2

i'm working w/ a legacy database is set-up stupidly with an index composed of a char id column and two char columns which make up a date and time, respectively. I have created a ICompositeUserTypefor the date and time columns to map to a single .NET DateTime property on my entity, which works by itself when not part of the id. i need to somehow use a composite id with key property mapping that includes my ICompositeUserType for mapping to the two char date and time columns. Apparently w/ my version of Fluent NHibernate, CompositeIdentityPart doesn't have a CustomTypeIs() method, so i can't just do the following in my override:

mapping.UseCompositeId()
    .WithKeyProperty(x => x.Id, CommonDatabaseFieldNames.Id)
    .WithKeyProperty(x => x.FileCreationDateTime)
    .CustomTypeIs<FileCreationDateTimeType>();

is something like this even possible w/ NHibernate let alone Fluent? I haven't been able to find anything on this.

UPDATE:

after reading the NHibernate documentation more carefully, i found out that NHibernate does support component composite IDs, but it doesn't look like it supports custom types (i.e. IUserType and ICompositeUserType) for composite IDs. Also, the version of Fluent i have doesn't have support for NHibernate's support of component composite IDs (see issue 387 and issue 346). i will probably try and upgrade my entire solution, see if it works, and post an answer to my own question if it does... unless someone can tell me w/o me having to do that... 8o)

A: 

Try adding this

mapping.Map(x => x.FileCreationDateTime).Columns.Add("FileCreationDate", "FileCreationTime").CustomSqlType("YourType");

Although I am not sure what sense CustomSqlType does when referring to two columns at once. Probably none. Can you create a view that projects these to columns to normal DateTime?

HeavyWave
i can't modify the database at all, unfortunately. if it was up to me, we would completely redesign the thing. so is your code sample dependent on the view you're suggesting, or can it be done w/o the view?
gabe
Without the view. Experiment with it, sometimes the best way to learn if something can be done with Fluent is to download the source code and look at unit tests. Although, I think you should just map each column to its own field and provide additional property that combines them.
HeavyWave
good idea on examining the UTs.the nice thing about combining the fields at the mapping using an icompositeusertype is that i don't have to have the legacy DB data access format translation in my domain object which should just contain business logic. i have a separation of concern for my data access translation and just the POCO class business logic. i'm trying to maintain this abstraction if i can. i can't mark this as the answer because the CompositeIdentityPart doesn't contain a Columns property. I need the FileCreationDateTime to be apart of the composite key/id.
gabe
You can use Map() alongside CompositeId(). But then again it will not help from my knowledge. I don't think what you want is doable without digging into the library's source.
HeavyWave
i can't mark your answer as the solution, because i doesn't contain the solution i ended-up w/. i did, however, vote you up for your comment that i end-up having to use as the solution.
gabe
A: 

NHibernate doesn't support the use of IUserType or ICompositeUserTypes for composite IDs. I does, however, support component composite IDs, but Fluent NHibernate has limited support for this. From what i could see in the source code, it doesn't allow you to specify the column names for the component properties like NHibernate allows. I had to give-up for now and just create two string fields that the two string date fields in the database could map to seperately, and then have a DateTime? property that translated the two string properties. Props to HeavyWave for their comment: "Although, I think you should just map each column to its own field and provide additional property that combines them."

mapping.CompositeId()
            .KeyProperty(x => x.Id, CommonDatabaseFieldNames.Id)
            .KeyProperty(x => x.FileCreationDateString, CommonDatabaseFieldNames.FileCreationDate)
            .KeyProperty(x => x.FileCreationTimeString, CommonDatabaseFieldNames.FileCreationTime);
gabe