문제

I have a many to many in sql and I'm trying to map it using nhibernate. I'm getting close now after struggles to get this far but my sql string that nhibernate creates has a question mark in it, shown below. Am I missing something?

do I need to create an add method in each class to add the other entity onto it?

Thanks,

My problem - sql string produced by fluent nhibernate

... y=productcat1_.itm_Key WHERE productcat0_.itr_Key=?

object A

public class Range : IEntity
{
    public virtual IList<Item> Items { get; set; }
}

object B

public class Item : IEntity
{
    public virtual IList<Range> Ranges { get; set; } 
}

Mappings

// Item mapping
mapping.HasManyToMany(x => x.Ranges)
            .Table("itr_RangeItemsAssoc")
            .ParentKeyColumn("itm_Key")
            .ChildKeyColumn("itr_ItemsKey")
            .Cascade.SaveUpdate().LazyLoad();

// Range mapping
mapping.HasManyToMany(x => x.Items)
            .Table("itr_RangeItemsAssoc")
            .ParentKeyColumn("itr_Key")
            .ChildKeyColumn("itr_ItemRangeKey")
            .Cascade.SaveUpdate().LazyLoad();

Update

Have added the following method onto my entities although I don't call them anywhere..?

public class Range : IEntity
{
    ....

    public virtual void AddItem(Item item)
    {
        item.Ranges.Add(this);
        Items.Add(item);
    }
}

public class Item : IEntity
{
    ...

    public virtual void AddRange(Range range)
    {
        range.Items.Add(this);
        Ranges.Add(range);
    }
}

Update 2 - mapping corrections

mapping.HasManyToMany(x => x.Ranges)
            .Table("itr_RangeItemsAssoc")  // name of the look up table
            .ParentKeyColumn("itr_ItemsKey")  // key for item in the lookup table
            .ChildKeyColumn("itm_Key")  // key column in the item table
            .Cascade.SaveUpdate().LazyLoad().Inverse();
    }


mapping.HasManyToMany(x => x.Items)
            .Table("itr_RangeItemsAssoc")  // name of the look up table
            .ParentKeyColumn("itr_ItemRangeKey")  // key for the range in the lookup tablei
            .ChildKeyColumn("itr_Key")  // key column in the range table
            .Cascade.SaveUpdate().LazyLoad();

Many thanks,

도움이 되었습니까?

해결책

There are two things to be mentioned.

Firstly, Many-to-many is represented by pairing table, with two columns. These are playing role parent-child and child-parent.

Secondly, one end must be marked as inverse. Below the Items are marked .Inverse()

There is an example of the Item mapping

public class ItemMap : ClassMap<Item>
{
    public LibraryMap()
    {
         // table, id, other properties
         ...
         HasManyToMany(x => x.Ranges)
            .Table("itr_RangeItemsAssoc")
            .ParentKeyColumn("itr_ItemRangeKey") // not itm_Key
            .ChildKeyColumn("itr_ItemsKey")
            .Cascade.SaveUpdate()
            .LazyLoad();

The similar for a Range

HasManyToMany(x => x.Items)
    .Table("itr_RangeItemsAssoc")
    .ParentKeyColumn("itr_ItemsKey") // not itr_Key
    .ChildKeyColumn("itr_ItemRangeKey")
    .Cascade.SaveUpdate()
    .LazyLoad()
    // here, the inverse
    .Inverse() // one end must be marked as inverse
    ;

Here you can get some idea about the mapping behind: 6.8. Bidirectional Associations

The example of the fluent mapping many-to-many could be found here: Mapping-by-Code - OneToMany and other collection-based relation types (the second half of the article)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top