Свободная проблема с отображением в Nhibernate HasMany - PullRequest
1 голос
/ 07 ноября 2010

Я новичок в Fluent и NHibernate, и я не уверен, как отобразить это конкретное отношение, которое существует в моей базе данных. У меня есть следующая диаграмма ER, которая обрисовывает в общих чертах мою структуру таблицы.

ER Diagram

Ниже приведены мои текущие классы сущностей 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);
        }
    }

1 Ответ

0 голосов
/ 15 апреля 2011

Единственный способ заставить это работать - изменить отображение для 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();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...