2

I have an entity like so:

public class Land
{
    public virtual IDictionary<string, int> Damages { get; set; }
    // and other properties
}

Every time I try to use automapping with the following code:

var sessionFactory = Fluently.Configure()
    .Database(SQLiteConfiguration.Standard.InMemory)
    .Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf<Land>))
    .BuildSessionFactory();

I get the following error:

{"The type or method has 2 generic parameter(s), but 1 generic argument(s) were
provided. A generic argument must be provided for each generic parameter."}

Can someone tell me what I'm doing wrong? Also, this is just a simple example. I have much more dictionaries than just this one.

Daniel T.
  • 37,212
  • 36
  • 139
  • 206
  • http://stackoverflow.com/questions/1410716/fluentnhibernate-mapping-for-dictionary Try AsMap() – mokha Sep 14 '12 at 16:38

3 Answers3

8

It is impossible with NHibernate.

user224564
  • 1,313
  • 1
  • 10
  • 14
  • Do you mean this to be impossible with Fluent NHibernate automapping, Fluent NHibernate as a whole (meaning with the fluent mappings as well), or NHibernate itself? – Daniel T. Jan 01 '10 at 02:05
  • NHibernate itself. I do not know any ORM that could automap dictionary at present moment. – user224564 Jan 03 '10 at 06:06
  • 8
    You're right, you have to manually map it. Using Fluent, it'd be `References(x => x.Dictionary).AsMap("keyColumn").Element("valueColumn", c => c.Type());`. – Daniel T. Jan 11 '10 at 05:18
3

Found some traces that this isn't possible. Some traces, that it's recently implemented.

Still investigating. :)


This looks quite promising (didn't test yet).

So, in your case it should look like=>

public class LandMap : ClassMap<Land>
{
    public LandMap()
    {
        (...)

        HasMany(x => x.Damages)
            .WithTableName("Damages")
            .KeyColumnNames.Add("LandId")
            .Cascade.All()
            .AsMap<string>(
                index => index.WithColumn("DamageType").WithType<string>(),
                element => element.WithColumn("Amount").WithType<int>()
            );
    }
}

Keep in mind - it should. I didn't test it.

Community
  • 1
  • 1
Arnis Lapsa
  • 45,880
  • 29
  • 115
  • 195
1

A possible workaround that should in theory work with automapping:

public class DamagesDictionary : Dictionary<string, int>
{
}

Land.cs

public class Land
{
   public virtual DamagesDictionary Damages { get; set; }
   // and other properties
}

or a more generic approach...

public class StringKeyedDictionary<T> : Dictionary<string, T>
{
}

Land.cs

public class Land
{
   public virtual StringKeyedDictionary<int> Damages { get; set; }
   // and other properties
}
Josef P.
  • 245
  • 1
  • 12
  • I think this is an underrated answer - simpler sometimes to make another POCO with 2 properties on it (Key, Value) and reference that if you can't be bothered to write the mappings (Lazy, yes.. Recommender, no... but...) – Darbio Nov 30 '11 at 05:01