使用Fluent Nhibernate Automapping进行多对多关系

时间:2012-02-17 07:42:09

标签: nhibernate fluent-nhibernate many-to-many automapping

我们正面临使用流畅的nhibernate自动化应用多对多关系的问题。

域模型的简化形式如下:

public class Group
{
    private readonly IList<Recipient> _recipients = new List<Recipient>();
    public virtual IList<Recipient> Recipients
    {
        get { return _recipients; }
    }
}

public class Recipient
{
    private readonly IList<Group> _groups = new List<Group>();
    public virtual IList<Group> Groups
    {
        get { return _ groups; }
    }
}

正如上面的代码所描述的那样,Group和Recipient具有多对多的关系。 我们使用流畅的nhibernate自动化功能来映射我们的域模型与数据库。因此,我们需要使用Convention进行自动化。 以下是我们用于多对多惯例的代码: -

public class ManyToManyConvention : IHasManyToManyConvention
{
    #region IConvention<IManyToManyCollectionInspector,IManyToManyCollectionInstance> Members

    public void Apply(FluentNHibernate.Conventions.Instances.IManyToManyCollectionInstance instance)
    {
        if (instance.OtherSide == null)
        {
            instance.Table(
               string.Format(
                   "{0}To{1}",
                   instance.EntityType.Name + "_Id",
                   instance.ChildType.Name + "_Id"));
        }
        else
        {
            instance.Inverse();
        }
        instance.Cascade.All();
    }

    #endregion
}

我在这里找到了这个解决方案:

http://blog.vuscode.com/malovicn/archive/2009/11/04/fluent-nhibernate-samples-auto-mapping-part-12.aspx#Many%20to%20Many%20convention

但在上面的代码中同时调试收件人的时间 - &gt;组和组 - &gt;收件人instance.OtherSide不是null。假设是第一次实例.OtherSide将不为null,第二次它将为null,因为关系应用于一侧,因此我们将对此应用反向。 所以它创建了两个相同的映射表。 数据库加载有2个相同模式的表。即使我尝试使用多对多关系将我们的域模型保存到数据库。它只保存1个边,即它将收件人保存在组中,但不保存收件人中的组。在数据库中,它只有一个映射表中的条目,而不是两个。

所以,问题是我们做得对吗?如果没有,那么该怎么做。

1 个答案:

答案 0 :(得分:2)

你可以将逆本身作为一个标准

    public void Apply(IManyToManyCollectionInstance instance)
    {
        Debug.Assert(instance.OtherSide != null);
        // Hack:  the cast is nessesary because the compiler tries to take the Method and not the property
        if (((IManyToManyCollectionInspector)instance.OtherSide).Inverse)
        {
            instance.Table(
               string.Format(
                   "{0}To{1}",
                   instance.EntityType.Name + "_Id",
                   instance.ChildType.Name + "_Id"));
        }
        else
        {
            instance.Inverse();
        }
        instance.Cascade.All();
    }