将Fluent NHibernate compositeid映射到映射类

将Fluent NHibernate compositeid映射到映射类,nhibernate,fluent-nhibernate,nhibernate-mapping,mapping,composite-id,Nhibernate,Fluent Nhibernate,Nhibernate Mapping,Mapping,Composite Id,我试图弄清楚如何使用CompositeId映射另一个类。下面是一个测试用例: 各表: TestParent: TestParentId (PK) FavoriteColor TestChild: TestParentId (PK) ChildName (PK) Age C#中的类: 公共类TestParent { 公共TestParent() { TestChildList=新列表(); } 公共虚拟int TestParentId{get;set;} 公共虚拟字符串Fa

我试图弄清楚如何使用CompositeId映射另一个类。下面是一个测试用例:

各表:

TestParent:
  TestParentId (PK)
  FavoriteColor

TestChild:
  TestParentId (PK)
  ChildName (PK)
  Age
C#中的类:

公共类TestParent
{
公共TestParent()
{
TestChildList=新列表();
}
公共虚拟int TestParentId{get;set;}
公共虚拟字符串FavoriteColor{get;set;}
公共虚拟IList TestChildList{get;set;}
}
公共类TestChild
{
公共虚拟测试父级{get;set;}
公共虚拟字符串ChildName{get;set;}
公共虚拟整数{get;set;}
公共覆盖int GetHashCode()
{
返回Parent.GetHashCode()^ChildName.GetHashCode();
}
公共覆盖布尔等于(对象对象对象)
{
if(obj是TestChild)
{
var toCompare=obj作为TestChild;
返回此.GetHashCode()!=toCompare.GetHashCode();
}
返回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 **/
    }
}
公共类TestParentMap:ClassMap
{
公共TestParentMap()
{
表(“TestParent”);
Id(x=>x.TestParentId).Column(“TestParentId”).GeneratedBy.Native();
Map(x=>x.FavoriteColor);
HasMany(x=>x.TestChildList).KeyColumn(“TestParentId”).Inverse().Cascade.None();
}
}
公共类TestChildMap:ClassMap
{
公共TestChildMap()
{
表(“TestChild”);
复合ID()
.KeyProperty(x=>x.ChildName,“ChildName”)
.KeyReference(x=>x.Parent,“TestParentId”);
Map(x=>x.Age);
引用(x=>x.Parent,“TestParentId”);/**中断插入**/
}
}
尝试添加新记录时,出现以下错误:

System.ArgumentOutOfRange异常: 索引超出范围。必须是 非负数且小于 收藏。参数名称:索引

我知道此错误是由于CompositeId和References调用中映射了TestParentId列造成的。但是,在基于TestParentId查询TestChild时,删除引用调用会导致另一个错误

下面是执行查询的代码:

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>();
var session=\u sessionBuilder.GetSession();
使用(var tx=session.BeginTransaction())
{
//创建父项
var p=newtestparent(){FavoriteColor=“Red”};
session.Save(p);
//创造孩子
var c=新的TestChild()
{
ChildName=“第一个孩子”,
父项=p,
年龄=4
};
session.Save(c);//在TestChildMap中使用引用中断调用
tx.Commit();
}
//在TestChildMap中不带引用的中断
var children=_sessionBuilder.GetSession().CreateCriteria()
.CreateAlias(“父级”、“p”)
.Add(Restrictions.Eq(“p.TestParentId”,1))
.List();

关于如何为该场景创建复合键,您有什么想法吗?

有什么原因不能将查询修改为

_sessionBuilder.GetSession().CreateCriteria<TestChild>()
   .Add(Restrictions.Eq("Parent.TestParentId", 1))
   .List<TestChild>()
\u sessionBuilder.GetSession().CreateCriteria()
.Add(Restrictions.Eq(“Parent.TestParentId”,1))
.List()

然后去掉引用?

我找到了一个更好的解决方案,可以进行查询和插入。关键是更新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
    }
}
公共类TestChildMap:ClassMap
{
公共TestChildMap()
{
表(“TestChild”);
复合ID()
.KeyProperty(x=>x.ChildName,“ChildName”)
.KeyReference(x=>x.Parent,“TestParentId”);
Map(x=>x.Age);
引用(x=>x.Parent,“TestParentId”)
.Not.Insert();//将避免插入时出现“索引超出范围”错误
}
}

谢谢-这很有效。我不确定它是否能修复所有的问题(可能需要加入TestChild和TestParent进行其他查询),但我想我以后会担心的。你让我很开心!非常感谢提问者和回答者!我也能算出它是以一种方式使用Insert的,而不是以读取方式,反之亦然,但我不会猜到这是一个解决方案。解决方案适合我,特别是代码行。not.Insert()
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
    }
}