Как сопоставить шаблон подотчетности с SQL с помощью NHibernate? - PullRequest
2 голосов
/ 20 января 2011

Мы реализовали нашу модель предметной области, используя шаблон подотчетности, который мы пытаемся сохранить, используя NHibernate с беглым NHibernate для определения карт.

Фактически у нас есть 3 сущности, Подотчетность (используется для определения взаимосвязи междустороны), Сторона (используется для определения стороны, например, контакт, лицо, бизнес и т. д.) и тип AccountabilityType (используется для указания отношения подотчетности, т. е. «принадлежит», «принадлежит» и т. д.)

Я являюсьврезаться в кирпичную стену с точки зрения определения карт.

ERD выглядит следующим образом (новые пользователи aaarrgg не могут публиковать изображения, жизнь и ее небольшие проблемы):

Я надеюсь, что карты высможет выяснить ERD.

Сущности определены следующим образом (они были ошарашены для тестирования):

public class AccountabilityType
{
    public virtual string Id { get; set; }

    public override int GetHashCode()
    {
        return Id.GetHashCode();
    }

    public override bool Equals(object obj)
    {
        var other = obj as AccountabilityType;
        if (other == null)
            return false;
        return other.GetHashCode() == GetHashCode();
    }
}


public class Accountability
{
    #region Properties

    public virtual Guid Id { get; set; }

    public virtual Party Parent { get; set; }

    public virtual Party Child { get; set; }

    public virtual AccountabilityType Type { get; set; }

    #endregion

    #region Methods

    public override int GetHashCode()
    {
        return Type.GetHashCode() ^ Parent.GetHashCode() ^ Child.GetHashCode();
    }

    public override bool Equals(object obj)
    {
        var other = obj as Accountability;
        if (other == null)
            return false;
        return other.GetHashCode() == GetHashCode();
    }

    #endregion
}

public class Party
{
    public Party()
    {
        ParentAccountabilities = new List<Accountability>();
        ChildAccountabilities = new List<Accountability>();
    }

    #region Properties

    public virtual Guid Id { get; set; }

    public virtual string Name { get; set; }

    public virtual string Type { get; set; }

    // Exposed for persistence, Hackity Hack, dont hate the player hate the game
    public virtual IList<Accountability> ParentAccountabilities { get; set; }

    // Exposed for persistence, Hackity Hack, dont hate the player hate the game
    public virtual IList<Accountability> ChildAccountabilities { get; set; }

    #endregion

    #region Overrides

    public override int GetHashCode()
    {
        return Type.GetHashCode() ^ Name.GetHashCode();
    }

    public override bool Equals(object obj)
    {
        var other = obj as Party;
        if (other == null)
            return false;
        return other.GetHashCode() == GetHashCode();
    }

    #endregion
}

И, наконец, текущие карты отображаются следующим образом:

public class AccountabilityTypeMap : ClassMap<AccountabilityType>
{
    public AccountabilityTypeMap()
    {
        Id(p => p.Id).GeneratedBy.Assigned();
    }
}

public class AccountabilityMap : ClassMap<Accountability>
{
    public AccountabilityMap()
    {
        Id(p => p.Id).GeneratedBy.Guid();

        References(p => p.Parent, "ParentId").Cascade.None();

        References(p => p.Child, "ChildId").Cascade.All();

        References(p => p.Type, "AccountabilityTypeId").Cascade.None();
    }
}

public class PartyMap : ClassMap<Party>
{
    public PartyMap()
    {
        Id(p => p.Id).GeneratedBy.Assigned();

        Map(p => p.Name);

        Map(p => p.Type);

        HasManyToMany(p => p.ChildAccountabilities)
            .Table("Accountability")
            .ParentKeyColumn("ChildId")
            .ChildKeyColumn("ParentId")
            .Cascade.All();

        HasManyToMany(p => p.ParentAccountabilities)
            .Table("Accountability")
            .ParentKeyColumn("ParentId")
            .ChildKeyColumn("ChildId")
            .Cascade.None()
            .Inverse();
    }
}

Объекты сохраняются в БД, однако NHibernate выдает ошибку session.Flush (), и ошибка указывает, чтоон пытается вставить объект подотчетности с нулевым идентификатором.Это в первую очередь невозможно, поскольку идентификатор является необнуляемым Guid, и я прошел через объектную модель, чтобы убедиться, что нет объекта с нулевым / пустым идентификатором.

Любые предложения будут наиболее цениться:)

Спасибо

Ответы [ 2 ]

0 голосов
/ 24 января 2011

Кажется, я запутался в отображении.Я не имею дело с отображением ManyToMany, так как я моделирую таблицу мостов в своем домене.Отображение должно выглядеть следующим образом.

public class AccountabilityTypeMap : ClassMap<AccountabilityType>
{
    public AccountabilityTypeMap()
    {
        Id(p => p.Id).GeneratedBy.Assigned();
    }
}

public class AccountabilityMap : ClassMap<Accountability>
{
    public AccountabilityMap()
    {
        Id(p => p.Id).GeneratedBy.Guid();

        References(p => p.Parent, "ParentId").Cascade.None();

        References(p => p.Child, "ChildId").Cascade.All();

        References(p => p.Type, "AccountabilityTypeId").Cascade.None();
    }
}

public class PartyMap : ClassMap<Party>
{
    public PartyMap()
    {
        Id(p => p.Id).GeneratedBy.Guid();

        Map(p => p.Name);

        Map(p => p.Type);

        HasMany(p => p.ChildAccountabilities)
            .KeyColumn("ParentId")
            .Inverse()
            .Cascade.All();

        HasMany(p => p.ParentAccountabilities)
            .KeyColumn("ChildId")
            .Inverse()
            .Cascade.All();
    }
}
0 голосов
/ 20 января 2011

Вы можете получить ноль, если Родитель не установлен на Ребенка. При добавлении дочернего объекта его родительское свойство должно быть установлено на родительский.

рассмотреть следующие вопросы:

var parent = new Party();
var child = new Accountability();
parent.ChildAccountabilities.Add(child);

Родитель знает о ребенке, но ребенок не знает о родителе. Попробуйте явно установить родителя для ребенка:

var parent = new Party();
var child = new Accountability();
child.Parent = parent;
parent.ChildAccountabilities.Add(child);

Если это решит проблему, то все сводится к тому, как вы хотите инкапсулировать установку свойства Parent при добавлении потомка. Эта запись в блоге может помочь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...