流利Nhibernate HasMany映射问题 [英] Fluent Nhibernate HasMany mapping issue

查看:99
本文介绍了流利Nhibernate HasMany映射问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Fluent和NHibernate的新手,我不确定如何映射数据库中存在的特定关系。我有下面的ER图,概述了我的表结构。





下面是我目前的C#实体类:

  public class GroupHeader 
{
public virtual Guid Id {get; private set;}
public virtual string Name {get;组; }
public virtual string描述{get;组; }
公共虚拟IList< RightHeader>权利{get;组; }
公共虚拟IList< GroupRight> GroupRights {get;组; }
public GroupHeader()
{
GroupRights = new List< GroupRight>();
Rights =新列表< RightHeader>();

公共GroupHeader(字符串名称,字符串描述,IList< RightHeader>权限)
:this()
{
Name = name;
说明=说明;
权利=权利;
$ b $ if(rights!= null)
foreach(RightHeader right in rights)
AddRight(right,1);

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



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

public GroupRight()
{

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

public class RightHeader
{
public virtual decimal Num {get;私人设置}
public virtual string Name {get;组; }
public virtual string描述{get;组; }
公共虚拟IList< GroupRight> GroupRights {get;组; }
$ b $ public RightHeader()
{

}
public RightHeader(十进制数,字符串名,字符串描述)
{
Num = num;
姓名=姓名;
说明=说明;




$ p $这些是我的流利的映射:$ / b

  public class GroupHeaderMap:ClassMap< GroupHeader> 
{
public GroupHeaderMap()
{
表(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()
{
表(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()
{
表(RIGHT_HEADER);
Id(x => x.Num,RIGHT_NUM);
地图(x => x.Name,RIGHT_NAME);
Map(x => x.Description,RIGHT_DESCRIPTION);

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






$ b当我运行我的单元测试时试图添加一个新的GroupHeader,GroupRight和RightHeader到我的数据库我得到以下错误:

NHibernate.Exceptions.GenericADOException:无法插入:[Business.Objects.GroupRight#Business.Objects .GroupRight] [SQL:INSERT INTO GROUP_RIGHT_COMPOSITE(RIGHT_VALUE,GROUP_ID,RIGHT_NUM)VALUES(?,?,?)] ---> System.Data.SqlClient.SqlException:INSERT语句与FOREIGN KEY约束FK_GROUP_RIGHTS_RIGHTS冲突。冲突发生在数据库TEST,表dbo.RIGHT_HEADER,列RIGHT_NUM。
该语句已被终止。

我很确定会发生这种情况,因为我创建的RIGHT_HEADER记录不在数据库中,它违反了外键约束,但我不知道如何映射,以便NHibernate将插入RIGHT_HEADER之前尝试创建GROUP_RIGHT_COMPOSITE记录。

编辑:
我正在使用的单元测试如下:

  [TestMethod()] 
public void GroupHeaderAddTest()
{
RightHeader newRight = new RightHeader(1,Some Right,允许用户做某事);
GroupHeader newGroup = new GroupHeader(Administrators,Administrative group,null,null);
newGroup.AddRight(newRight,1); (NHibernate.ISession session = SessionOrigin.Current.GetSession())

使用(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 not not null);
Assert.AreEqual< GroupHeader>(newGroup,foundGroup);


$ / code $ / pre

解决方案

只有这样,我可以得到这个工作是通过改变我的GroupRight到以下映射:

pre $公共类GroupRightMap:ClassMap< GroupRight> ;
{
public GroupRightMap()
{

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

引用(x => x.Group,GROUP_ID)
.Not.Update()
.Not.Insert()
.Cascade.All ();

引用(x => x.Right,RIGHT_NUM)
.Not.Update()
.Not.Insert()
.Cascade.All ();

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


I'm new to Fluent and NHibernate and I'm not sure how to map this specific relationship that exists in my database. I have the following ER diagram below that outlines my table structure.

Below are my current C# entity classes:

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:

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". The conflict occurred in database "TEST", table "dbo.RIGHT_HEADER", column '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.

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:

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();
    }
}

这篇关于流利Nhibernate HasMany映射问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆