我是Fluent和NHibernate的新手,我不确定如何映射我的数据库中存在的这种特定关系。我在下面的ER图中概述了我的表格结构。
以下是我目前的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;
}
}
这些是我流利的映射:
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");
}
}
每当我运行我的单元测试尝试将新的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(?,?,?)] - - &GT; 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", "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);
}
}
答案 0 :(得分:0)
我能让这个工作的唯一方法是将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();
}
}