NHibernate Free Composition for Associated Class

I am trying to figure out how to use CompositeId to map another class. Here's a test case:

Tables:

TestParent:
  TestParentId (PK)
  FavoriteColor

TestChild:
  TestParentId (PK)
  ChildName (PK)
  Age

Classes in 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;
    }
}

Free NHibernate Cards:

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 **/
    }
}

When I try to add a new entry, I get this error:

System.ArgumentOutOfRangeException: The index was out of reach. Must be non-negative and smaller than the size of the collection. Parameter Name: Index

I know this error is due to the fact that the TestParentId column is displayed in calls to CompositeId and References. However, deleting the References call causes another error when querying TestChild based on TestParentId.

Here is the code that executes the queries:

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>();

Any ideas on how to create a composite key for this scenario?

+3
2

, . 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
    }
}
+11

, ,

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

?

+2

All Articles