将多对多关系映射为IDictionary

时间:2011-08-15 21:35:11

标签: nhibernate fluent-nhibernate

我正在尝试映射具有多对多关系的Person和Address类。我想将Address集合映射为IDictionary,并将Address属性Type作为键。该关系仅从人员侧映射。

public class Person
{
    public IDictionary<int, Address> Addresses { get; set; }
}

public class Address
{
    public int Type { get; set; }
}

我正在使用的映射是:

HasManyToMany<Address>(x => x.Addresses).Table("PersonAddress")
    .ParentKeyColumn("PersonId").ChildKeyColumn("AddressId")
    .AsMap(x => x.Type);

问题是发出的SQL是:

SELECT addressesd0_.PersonId    as PersonId1_,
   addressesd0_.AddressId       as AddressId1_,
   addressesd0_.Type            as Type1_,
   address1_.AddressId          as AddressId5_0_
   -- etc.
FROM   dbo.PersonAddress addressesd0_
   left outer join dbo.Address address1_
     on addressesd0_.AddressId = address1_.AddressId
WHERE  addressesd0_.PersonId = 420893

它试图从多对多连接表中选择Type,该表不存在。我已经尝试了一些映射变体而没有成功。

我该如何映射?

2 个答案:

答案 0 :(得分:5)

这是不可能的。字典需要关系表中的键值。您拥有的表格结构是一个简单的多对多包或套装。

我会做的是将其映射为普通的包或套装,并在实体中提供类似访问的字典:

public class Person
{
    private IList<Address> addresses;

    public IEnumerable<Address> Addresses { get { return addresses; } }

    public Address GetAddressOfType(int addressType)
    {
      return addresses.FirstOrDefault(x => x.Type == addressType);
    }

    public void SetAddress(Address address)
    {
      var existing = GetAddressOfType(address.Type);
      if (existing != null)
      {
        addresses.Remove(existing);
      }
      addresses.Add(address);
    }
}

答案 1 :(得分:0)

您需要使用组件:

HasMany<Address>(x => x.Addresses) 
               .AsMap<int>("FieldKey")  
               .Component(x => x.Map(c => c.Id));