Свободный NHibernate композитид для сопоставленного класса - PullRequest
3 голосов
/ 21 марта 2011

Я пытаюсь выяснить, как использовать CompositeId для сопоставления другого класса.Вот тестовый пример:

Таблицы:

TestParent:
  TestParentId (PK)
  FavoriteColor

TestChild:
  TestParentId (PK)
  ChildName (PK)
  Age

Классы в C #:

public class TestParent
{
    public TestParent()
    {
        TestChildList = new List<TestChild>();
    }

    public virtual int TestParentId { get; set; }
    public virtual string FavoriteColor { get; set; }
    public virtual IList<TestChild> TestChildList { get; set; }
}

public class TestChild
{
    public virtual TestParent Parent { get; set; }
    public virtual string ChildName { get; set; }
    public virtual int Age { get; set; }

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

    public override bool Equals(object obj)
    {
        if (obj is TestChild)
        {
            var toCompare = obj as TestChild;
            return this.GetHashCode() != toCompare.GetHashCode();
        }
        return false;
    }
}

Карты Fluent NHibernate:

public class TestParentMap : ClassMap<TestParent>
{
    public TestParentMap()
    {
        Table("TestParent");
        Id(x => x.TestParentId).Column("TestParentId").GeneratedBy.Native();
        Map(x => x.FavoriteColor);

        HasMany(x => x.TestChildList).KeyColumn("TestParentId").Inverse().Cascade.None();
    }
}

public class TestChildMap : ClassMap<TestChild>
{
    public TestChildMap()
    {
        Table("TestChild");
        CompositeId()
            .KeyProperty(x => x.ChildName, "ChildName")
            .KeyReference(x => x.Parent, "TestParentId");

        Map(x => x.Age);
        References(x => x.Parent, "TestParentId");  /**  breaks insert **/
    }
}

Когда я пытаюсь добавить новую запись, я получаю эту ошибку:

System.ArgumentOutOfRangeException: индекс был вне диапазона.Должен быть неотрицательным и меньшим, чем размер коллекции.Имя параметра: index

Я знаю, что эта ошибка связана с отображением столбца TestParentId в вызовах CompositeId и References.Однако удаление вызова References вызывает еще одну ошибку при запросе TestChild на основе TestParentId.

Вот код, который выполняет запросы:

var session = _sessionBuilder.GetSession();
using (var tx = session.BeginTransaction())
{
    // create parent
    var p = new TestParent() { FavoriteColor = "Red" };
    session.Save(p);

    // creat child
    var c = new TestChild()
                {
                    ChildName = "First child",
                    Parent = p,
                    Age = 4
                };
    session.Save(c);  // breaks with References call in TestChildMap 

    tx.Commit();
}

// breaks without the References call in TestChildMap 
var children = _sessionBuilder.GetSession().CreateCriteria<TestChild>()
    .CreateAlias("Parent", "p")
    .Add(Restrictions.Eq("p.TestParentId", 1))
    .List<TestChild>();

Любые идеи о том, как создать составной ключ дляэтот сценарий?

Ответы [ 2 ]

11 голосов
/ 30 марта 2011

Я нашел лучшее решение, которое позволит запрашивать и вставлять. Ключ обновляет карту для TestChild, чтобы не вставлять записи. Новая карта:

public class TestChildMap : ClassMap<TestChild>
{
    public TestChildMap()
    {
        Table("TestChild");
        CompositeId()
            .KeyProperty(x => x.ChildName, "ChildName")
            .KeyReference(x => x.Parent, "TestParentId");

        Map(x => x.Age);
        References(x => x.Parent, "TestParentId")
            .Not.Insert();  //  will avoid "Index was out of range" error on insert
    }
}
2 голосов
/ 21 марта 2011

Любая причина, по которой вы не можете изменить свой запрос, чтобы он был просто

_sessionBuilder.GetSession().CreateCriteria<TestChild>()
   .Add(Restrictions.Eq("Parent.TestParentId", 1))
   .List<TestChild>()

Тогда избавьтесь от ссылки?

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