简体   繁体   English

流利的Nhibernate HasMany映射问题

[英]Fluent Nhibernate HasMany mapping issue

I'm new to Fluent and NHibernate and I'm not sure how to map this specific relationship that exists in my database. 我是Fluent和NHibernate的新手,我不确定如何映射数据库中存在的这种特定关系。 I have the following ER diagram below that outlines my table structure. 我下面有下面的ER图,概述了我的表结构。

ER图

Below are my current C# entity classes: 以下是我当前的C#实体类:

public class GroupHeader
{
    public virtual Guid Id { get; private set;}
    public virtual string Name { get; set; }
    public virtual string Description { get; set; }
    public virtual IList<RightHeader> Rights { get; set; }
    public virtual IList<GroupRight> GroupRights { get; set; }
    public GroupHeader()
    {
        GroupRights = new List<GroupRight>();
        Rights = new List<RightHeader>();
    }
    public GroupHeader(string name, string description, IList<RightHeader> rights)
        : this()
    {
        Name = name;
        Description = description;
        Rights = rights;

        if (rights != null)
            foreach (RightHeader right in rights)
                AddRight(right, 1);
    }

    public virtual void AddRight(RightHeader newRight, decimal rightValue)
    {
        GroupRight newGroupRight = new GroupRight(this, newRight, rightValue);
        GroupRights.Add(newGroupRight);
    }
}

public class GroupRight
{
    public virtual GroupHeader Group { get; set; }
    public virtual RightHeader Right { get; set; }
    public virtual decimal RightValue { get; set; }

    public GroupRight()
    {

    }
    public GroupRight(GroupHeader group, RightHeader right, decimal rightValue)
    {
        Group = group;
        Right = right;
        RightValue = rightValue;
    }
}

public class RightHeader
{
    public virtual decimal Num { get; private set; }
    public virtual string Name { get; set; }
    public virtual string Description { get; set; }
    public virtual IList<GroupRight> GroupRights { get; set; }

    public RightHeader()
    {

    }
    public RightHeader(decimal num, string name, string description)
    {
        Num = num;
        Name = name;
        Description = description;
    }
}

These are my fluent mappings: 这些是我流利的映射:

public class GroupHeaderMap : ClassMap<GroupHeader>
{
    public GroupHeaderMap()
    {
        Table("GROUP_HEADER");
        Id(x => x.Id, "GROUP_ID");
        Map(x => x.Name, "GROUP_NAME").Unique();
        Map(x => x.Description, "GROUP_DESCRIPTION");
        HasMany(x => x.GroupRights)
            .Table("GROUP_RIGHT_COMPOSITE")
            .KeyColumns.Add("GROUP_ID")
            .Cascade.AllDeleteOrphan();
    }
}

public class GroupRightMap : ClassMap<GroupRight>
{
    public GroupRightMap()
    {
        Table("GROUP_RIGHT_COMPOSITE");
        CompositeId()
            .KeyReference(x => x.Group, "GROUP_ID")
            .KeyReference(x => x.Right, "RIGHT_NUM");

        Map(x => x.RightValue, "RIGHT_VALUE").Not.Nullable();
    }
}

public class RightHeaderMap : ClassMap<RightHeader>
{
    public RightHeaderMap()
    {
        Table("RIGHT_HEADER");
        Id(x => x.Num, "RIGHT_NUM");
        Map(x => x.Name, "RIGHT_NAME");
        Map(x => x.Description, "RIGHT_DESCRIPTION");

        HasMany(x => x.GroupRights)
            .Inverse()
            .Table("GROUP_RIGHT_COMPOSITE")
            .KeyColumn("RIGHT_NUM");
    }
}

Whenever I run my unit test that attempts to add a new GroupHeader, GroupRight and RightHeader to my database I get the following error: 每当我运行尝试将新的GroupHeader,GroupRight和RightHeader添加到数据库的单元测试时,都会出现以下错误:

NHibernate.Exceptions.GenericADOException: could not insert: [Business.Objects.GroupRight#Business.Objects.GroupRight][SQL: INSERT INTO GROUP_RIGHT_COMPOSITE (RIGHT_VALUE, GROUP_ID, RIGHT_NUM) VALUES (?, ?, ?)] ---> System.Data.SqlClient.SqlException: The INSERT statement conflicted with the FOREIGN KEY constraint "FK_GROUP_RIGHTS_RIGHTS". NHibernate.Exceptions.GenericADOException:无法插入:[Business.Objects.GroupRight#Business.Objects.GroupRight] [SQL:插入GROUP_RIGHT_COMPOSITE(RIGHT_VALUE,GROUP_ID,RIGHT_NUM)值(?,?,?)]->系统.Data.SqlClient.SqlException:INSERT语句与FOREIGN KEY约束“ FK_GROUP_RIGHTS_RIGHTS”冲突。 The conflict occurred in database "TEST", table "dbo.RIGHT_HEADER", column 'RIGHT_NUM'. 数据库“ TEST”的表“ dbo.RIGHT_HEADER”的列“ RIGHT_NUM”中发生了冲突。 The statement has been terminated. 该语句已终止。

I'm pretty sure this happens because the RIGHT_HEADER record that I'm creating is not in the database and it's violating the foreign key constraint but I'm not sure how to map this so that NHibernate will insert the RIGHT_HEADER first before attempting to create the GROUP_RIGHT_COMPOSITE record. 我很确定会发生这种情况,因为我正在创建的RIGHT_HEADER记录不在数据库中,并且违反了外键约束,但是我不确定如何映射它,以便NHibernate在尝试创建之前先插入RIGHT_HEADER GROUP_RIGHT_COMPOSITE记录。

EDIT: The unit test I'm using is as follows: 编辑:我正在使用的单元测试如下:

    [TestMethod()]
    public void GroupHeaderAddTest()
    {
        RightHeader newRight = new RightHeader(1, "Some Right", "Allows user to do something");
        GroupHeader newGroup = new GroupHeader("Administrators", "Administrative group", null, null);
        newGroup.AddRight(newRight, 1);

        using (NHibernate.ISession session = SessionOrigin.Current.GetSession())
        {
            using (NHibernate.ITransaction tran = session.BeginTransaction())
            {
                session.SaveOrUpdate(newGroup);
                tran.Commit();
            }

            GroupHeader foundGroup = session.CreateCriteria<GroupHeader>()
                                .Add(Example.Create(newGroup))
                                .UniqueResult<GroupHeader>();

            Assert.IsNotNull(foundGroup, "Group should not be null");
            Assert.AreEqual<GroupHeader>(newGroup, foundGroup);
        }
    }

The only way I could get this to work was by changing my mapping for GroupRight to the following: 我可以使它起作用的唯一方法是将GroupRight的映射更改为以下内容:

public class GroupRightMap : ClassMap<GroupRight>
{
    public GroupRightMap()
    {

        Table("GROUP_RIGHT_COMPOSITE");
        CompositeId()
            .KeyReference(x => x.Group, "GROUP_ID")
            .KeyReference(x => x.Right, "RIGHT_NUM");

        References(x => x.Group, "GROUP_ID")
            .Not.Update()
            .Not.Insert()
            .Cascade.All();

        References(x => x.Right, "RIGHT_NUM")
            .Not.Update()
            .Not.Insert()
            .Cascade.All();

        Map(x => x.RightValue, "RIGHT_VALUE").Not.Nullable();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM