c# - 如何使用 NHibernate 将责任模式映射到 SQL

标签 c# .net nhibernate orm design-patterns

我们已经使用责任模式实现了我们的领域模型,我们正试图坚持使用 NHibernate 和流畅的 NHibernate 来定义映射。

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

我在定义 map 方面遇到了障碍。

ERD 看起来像这样(aaarrgg 新用户无法发布图片、生活及其小挑战):

我希望您能从 map 中找出 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
}

最后的fluent maps如下:

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() 上抛出一个错误,该错误表明它正在尝试插入一个 ID 为 NULL 的 Accountability 实体。这首先是不可能的,因为 Id 是一个不可为 null 的 Guid,而且我已经通过对象模型来确保不存在具有 null/空 id 的对象。

任何建议将不胜感激:)

谢谢

最佳答案

如果未在子对象上设置父对象,您可以获得空值。添加 Child 对象时,必须将其 Parent 属性设置为父对象。

考虑:

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

parent 知道 child ,但 child 不知道 parent 。尝试显式设置 child 的 parent :

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

如果这能解决问题,那么问题就在于您希望如何在添加子项时封装 Parent 属性的设置。 This blog entry可能有帮助。

关于c# - 如何使用 NHibernate 将责任模式映射到 SQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4745117/

相关文章:

c# - 我想要一个 ORM 吗?

c# - 如何在 C# 中将类型转换为 TEnum

.net - 如何在 ColdFusion 中设置 .NET 枚举

.net - WPF 中的 StaticResource 和 DynamicResource 有什么区别?

.net - 我可以创建一个没有项目文件的 nuget 包吗

database - Hibernate,将多个列分配为主键

c# - 您可以在自己的初始化行中使用变量(字典中的 tryGetOrElse)吗?

c# - 为什么精确的图像没有精确的描述符?

c# - 将 CMS 集成到 ASP.NET MVC Web 应用程序中?

c# - 有人在 Nhibernate 中使用 ASP.NET MembershipProvider 吗?