views:

630

answers:

3

Fluent NHibernate doesnt like this, throwing an error '{"Association references unmapped class: System.String"}'. Ok fine, I can see why this would cause a problem - but whats the best solution?

I dont really want it to store a delimited list of strings in a single field, this would get ugly if my list contains many strings.

I also dont really want a table 'string', for obvious reasons.

I guess I can solve this by wrapping my List inside a class,but this feels a little heavyweight. I'm starting to think its the best solution though.

Whats the best way to get Fluent NHibernate to handle this?

edit for clarification: I totally expect these values to be stored in another table. I thought perhaps that I may have been able to setup some automapping convention that instructs NHibernate 'If you see a class X that contains List<some primitive type>, then go ahead and automatically create a reference table that maps to this collection.

It feels a bit heavy to go and wrap every single collection in a class. If that is the best solution however, then so be it.

+1  A: 

Think of it this way...how would you do it without hibernate? Well, You'd probably have a table with a foreign-key and string column? Now, how do you do that with Hibernate? You setup another class with a many-to-one and string property. Then you map a collection of that class.

dotjoe
Ok, point taken. I just dont like having to create all these totally trivial classes to wrap primitive collections. Can I have the automapping infer this for me?
Alex
Oh, so you don't need to create another class? I think that's possible...http://nhforge.org/doc/nh/en/index.html#collections-ofvalues see how they gave an example of a set of ints, looks like you do a regular collection then define an element property for your string.
dotjoe
+4  A: 

I had this exact same issue a few weeks back, with floats instead of strings.

how-do-you-automap-listfloat-or-float-with-fluent-nhibernate

It turns out that Automapping does not work with primitive types.

Edit - This is no longer true - the FNH team has fixed the problem

There's a lot of sample code in the accepted answer to my question, but the key point is to add an override for your lists of primitive types ("RawY" in the example below):

public class DlsAppOverlordExportRunData
{
    public virtual int Id { get; set; }
    // Note: List<float> needs overrides in order to be mapped by NHibernate.
    // See class DlsAppOverlordExportRunDataMap.
    public virtual IList<float> RawY { get; set; }
}


// Must be in different namespace from DlsAppOverlordExportRunData!!!
public class DlsAppOverlordExportRunDataMap : IAutoMappingOverride<DlsAppOverlordExportRunData>
{
    public void Override(AutoMapping<DlsAppOverlordExportRunData> mapping)
    {
        // Creates table called "RawY", with primary key
        // "DlsAppOverlordExportRunData_Id", and numeric column "Value"
        mapping.HasMany(x => x.RawY)
               .Element("Value");
    }
}

I would expect the same approach to work with ILists of strings.

Tom Bushell
Ok this looks interesting. Is this something that can be defined via conventions? It seems FNH is focussing on conventions to customise automapping.
Alex
I don't think so. I got the solution by asking the question on the Fluent mailing list, and believe it was one of the FNH authors who gave it to me. If it could be done by a single convention, I think he would have suggested that.
Tom Bushell
A: 

Since I posted my first answer, the Fluent NHibernate team have fixed this problem.

You can now automap ILists of C# value types (strings, ints, floats, etc).

Just make sure you have a recent version of FNH.

Tom Bushell
Alas, this is almost a year late for my needs - regardless its good to see FNH implemented this, it was the only real hurdle I encountered when using it for a large LOB app.
Alex