如何使用NHibernate将Accountability模式映射到SQL

时间:2011-01-20 08:58:54

标签: c# .net nhibernate orm design-patterns

我们使用问责模式实现了我们的域模型,我们试图使用NHibernate和流畅的NHibernate来定义地图。

实际上我们有3个实体,Accountability(用于定义各方之间的关系),Party(用于定义方,即联系人,人,业务等)和AccountabilityType(用于指定责任关系,即“Belongs”) “,”由“等”拥有

在定义地图方面,我遇到了一堵砖墙。

ERD看起来像这样(aaarrgg新用户无法发布图像,生活和它的小挑战):

我希望从地图中你可以找出ERD。

实体定义如下(它们已被愚弄以进行测试):

public class AccountabilityType
{
    public virtual string Id { get; set; }

    public override int GetHashCode()
    {
        return Id.GetHashCode();
    }

    public override bool Equals(object obj)
    {
        var other = obj as AccountabilityType;
        if (other == null)
            return false;
        return other.GetHashCode() == GetHashCode();
    }
}


public class Accountability
{
    #region Properties

    public virtual Guid Id { get; set; }

    public virtual Party Parent { get; set; }

    public virtual Party Child { get; set; }

    public virtual AccountabilityType Type { get; set; }

    #endregion

    #region Methods

    public override int GetHashCode()
    {
        return Type.GetHashCode() ^ Parent.GetHashCode() ^ Child.GetHashCode();
    }

    public override bool Equals(object obj)
    {
        var other = obj as Accountability;
        if (other == null)
            return false;
        return other.GetHashCode() == GetHashCode();
    }

    #endregion
}

public class Party
{
    public Party()
    {
        ParentAccountabilities = new List<Accountability>();
        ChildAccountabilities = new List<Accountability>();
    }

    #region Properties

    public virtual Guid Id { get; set; }

    public virtual string Name { get; set; }

    public virtual string Type { get; set; }

    // Exposed for persistence, Hackity Hack, dont hate the player hate the game
    public virtual IList<Accountability> ParentAccountabilities { get; set; }

    // Exposed for persistence, Hackity Hack, dont hate the player hate the game
    public virtual IList<Accountability> ChildAccountabilities { get; set; }

    #endregion

    #region Overrides

    public override int GetHashCode()
    {
        return Type.GetHashCode() ^ Name.GetHashCode();
    }

    public override bool Equals(object obj)
    {
        var other = obj as Party;
        if (other == null)
            return false;
        return other.GetHashCode() == GetHashCode();
    }

    #endregion
}

最后流畅的地图如下:

public class AccountabilityTypeMap : ClassMap<AccountabilityType>
{
    public AccountabilityTypeMap()
    {
        Id(p => p.Id).GeneratedBy.Assigned();
    }
}

public class AccountabilityMap : ClassMap<Accountability>
{
    public AccountabilityMap()
    {
        Id(p => p.Id).GeneratedBy.Guid();

        References(p => p.Parent, "ParentId").Cascade.None();

        References(p => p.Child, "ChildId").Cascade.All();

        References(p => p.Type, "AccountabilityTypeId").Cascade.None();
    }
}

public class PartyMap : ClassMap<Party>
{
    public PartyMap()
    {
        Id(p => p.Id).GeneratedBy.Assigned();

        Map(p => p.Name);

        Map(p => p.Type);

        HasManyToMany(p => p.ChildAccountabilities)
            .Table("Accountability")
            .ParentKeyColumn("ChildId")
            .ChildKeyColumn("ParentId")
            .Cascade.All();

        HasManyToMany(p => p.ParentAccountabilities)
            .Table("Accountability")
            .ParentKeyColumn("ParentId")
            .ChildKeyColumn("ChildId")
            .Cascade.None()
            .Inverse();
    }
}

实体持久存储到数据库,但NHibernate在session.Flush()上抛出错误,并且错误表明它正在尝试插入具有NULL id的Accountability实体。这首先是不可能的,因为Id是一个不可为空的Guid,我已经通过对象模型来确保没有具有null / empty id的对象。

任何建议都会非常感激:)

由于

2 个答案:

答案 0 :(得分:0)

如果没有在Child上设置Parent,则可以获取null。添加Child对象时,其Parent属性必须设置为父对象。

考虑:

var parent = new Party();
var child = new Accountability();
parent.ChildAccountabilities.Add(child);

父母知道孩子,但孩子不知道父母。尝试明确设置子项上的父项:

var parent = new Party();
var child = new Accountability();
child.Parent = parent;
parent.ChildAccountabilities.Add(child);

如果这样可以解决问题,那么它只能归结为在添加子项时如何封装设置Parent属性。 This blog entry可能有帮助。

答案 1 :(得分:0)

似乎我把映射弄糊涂了。我没有处理ManyToMany映射,因为我正在为我的域中的桥表建模。映射应该如下所示。

public class AccountabilityTypeMap : ClassMap<AccountabilityType>
{
    public AccountabilityTypeMap()
    {
        Id(p => p.Id).GeneratedBy.Assigned();
    }
}

public class AccountabilityMap : ClassMap<Accountability>
{
    public AccountabilityMap()
    {
        Id(p => p.Id).GeneratedBy.Guid();

        References(p => p.Parent, "ParentId").Cascade.None();

        References(p => p.Child, "ChildId").Cascade.All();

        References(p => p.Type, "AccountabilityTypeId").Cascade.None();
    }
}

public class PartyMap : ClassMap<Party>
{
    public PartyMap()
    {
        Id(p => p.Id).GeneratedBy.Guid();

        Map(p => p.Name);

        Map(p => p.Type);

        HasMany(p => p.ChildAccountabilities)
            .KeyColumn("ParentId")
            .Inverse()
            .Cascade.All();

        HasMany(p => p.ParentAccountabilities)
            .KeyColumn("ChildId")
            .Inverse()
            .Cascade.All();
    }
}