12
votes

Fluent NHibernate doesn't like this, throwing an error:

{"Association references unmapped class: System.String"}

OK fine, I can see why this would cause a problem - but what's the best solution?

I don't 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 don't really want a table 'string', for obvious reasons.

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

What's the best way to get Fluent NHibernate to handle this?

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.

3
if you don't want it as a delimited string in a single field, and you don't want it in another table, then where? this is still a relational database...Mauricio Scheffer
I'm not bothered by how the relational database handles this. I'm wondering how I can get the automapping to infer this is what I want to do for all string lists in my domain model.Alex
@Alex - as far as I know, there's no way to tell Fluent NHibernate how to map ALL lists of strings. The solution I provide in my answer requires an override for each list of strings in your domain model. It's only a couple of lines of code for each override, so it's not too bad...Tom Bushell
I come across this today and found a simpler solution (Region with a list of country codes): HasMany(x => x.Countries).KeyColumn("CNTRY_REGION_CD").Element("value");Jim Schubert

3 Answers

7
votes

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.

4
votes

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.

1
votes

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.