简体   繁体   English

流畅的NHibernate compositeid到映射类

[英]Fluent NHibernate compositeid to mapped class

I'm trying to figure out how to use CompositeId to map another class. 我正在试图弄清楚如何使用CompositeId来映射另一个类。 Here's a test case: 这是一个测试用例:

The tables: 表格:

TestParent:
  TestParentId (PK)
  FavoriteColor

TestChild:
  TestParentId (PK)
  ChildName (PK)
  Age

The classes in C#: 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;
    }
}

The Fluent NHibernate maps: 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 **/
    }
}

When I try to add a new record, I get this error: 当我尝试添加新记录时,我收到此错误:

System.ArgumentOutOfRangeException : Index was out of range. System.ArgumentOutOfRangeException:索引超出范围。 Must be non-negative and less than the size of the collection. 必须是非负数且小于集合的大小。 Parameter name: index 参数名称:index

I know this error is due to the TestParentId column being mapped in the CompositeId and References calls. 我知道这个错误是由于在CompositeId和References调用中映射了TestParentId列。 However, removing the References call causes another error when querying TestChild based on the TestParentId. 但是,在基于TestParentId查询TestChild时,删除References调用会导致另一个错误。

Here's the code that does 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? 有关如何为此方案创建组合键的任何想法?

I found a better solution that will allow querying and inserting. 我找到了一个更好的解决方案,允许查询和插入。 The key is updating the map for TestChild to not insert records. 关键是更新TestChild的映射以不插入记录。 The new map is: 新地图是:

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

Any reason you can't modify your query to just be 您无法修改查询的任何原因

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

Then get rid of the reference? 然后摆脱参考?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM