views:

50

answers:

1

Using the following classes..

public class Trait
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
}
public class Sheet
{
    public virtual int Id { get; set; }
    public virtual IDictionary<Trait, int> Influences { get; set; }
}

I have tried to map them using Fluent nHibernate, as such.

public class TraitMap : ClassMap<Trait>
{
    public TraitMap()
    {
        Id(x => x.Id);
        Map(x => x.Name);
        Table("Traits");
    }
}
public class SheetMap : ClassMap<Sheet>
{
    public SheetMap()
    {
        Id(x => x.Id);

        HasManyToMany<Trait>(x => x.Influences)
            .Schema("Sheets")
            .Table("Influences")
            .ParentKeyColumn("Trait")
            .ChildKeyColumn("Sheet")
            .AsMap<int>("Rating")
            .Cascade.All();

        Table("Sheets");
    }
}

This does not work. I get the exception.

Exception occurred getter of Trait.Id

Now, if I change the Dictionary up to look like this..

public class Sheet
{
    public virtual int Id { get; set; }
    public virtual IDictionary<int, Trait> Influences { get; set; }
}

Basically making the int the Key, and the Trait the value (not what I want), it does work. Can anyone explain this, and how I can more appropriately reproduce what I am trying to do?

I think the reasoning is because when I specify HasManyToMany<Trait> I am specifying the Value element of the collection. However this is not my intention.

I want to look things up by the Name of the Key, not the Name of the Value. While I realize this is technically an 'acceptable' solution, it kind of goes against the Dictionary convention. I'd prefer to take a more convention over solution approach, if at all possible - and I'd like to better understand what is actually going on under the hood.

+1  A: 

What you want is what <composite-index> mapping in hbm would give you. I believe that instead of AsMap, you'd want AsEntityMap. However, look at this thread which talks about a rewrite (in august) of the fluent mapping for Maps that makes all of the above obsolete.

EDIT : For AsEntityMap, and other options, take a look at this SO question and answer

  HasMany<Trait>(x => x.Influences)
    .KeyColumn("key column name")
    .AsEntityMap("referenced column name")
    .Entity("dict value", v=> v.Type<int>());

Also, you say you're on the latest version - the latest release is 1.1, but trunk is 2.0, and is very different, and much further along. If you're not on 2.0+, you wouldn't see the methods posted in most of the help threads like the one linked above.

Philip Rieck
I have read that thread, and unfortunately it did not make much sense to me. I actually found it before I even posted this question. Furthermore, I have the latest build of fluent nhibernate, and I did not find the .Index method from HasMany().
Stacey
Could I bother you to cite an example of how I might use AsEntityMap to fix this? I am still quite confused.
Stacey
@Stacey Added some edits, hope that helps 1.1 and 2.0 are so different that it's hard to find help (the experts are on 2.0, but the released ver is 1.1) - and hard to remove.
Philip Rieck
I'm not sure what you mean by 'Trunk'. I don't use github, and I'm having a very hard time following how to download the appropriate files.
Stacey
Have you downloaded the latest build or 1.1? If the latest build is significantly different from 1.1 when it comes to Dictionary support.
James Gregory
I go to http://github.com/jagregory/fluent-nhibernate and click on the "Downloads" button. Then I click "Download Zip", it says "Branch Master". I get a file named jagregory-fluent-nhibernate-release-1.1-27-ga52c03d.zip
Stacey