Я новичок в 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) ЗНАЧЕНИЯ (?,??) -> 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.
EDIT:
Модульный тест, который я использую, выглядит следующим образом:
[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);
}
}