C# 通过包含多列的主键上的代码定义NHibernate映射

C# 通过包含多列的主键上的代码定义NHibernate映射,c#,nhibernate,nhibernate-mapping,C#,Nhibernate,Nhibernate Mapping,有没有人想到只使用NHibernate映射在多个列上创建引用?此映射只允许一列 Bag(p => p.Childs, map => { map.Key(k => { k.Column("KeyPart1"); }); map.Key(k => { k.Column("KeyPart2");

有没有人想到只使用NHibernate映射在多个列上创建引用?此映射只允许一列

Bag(p => p.Childs,
    map =>
    {
        map.Key(k =>
            {
                k.Column("KeyPart1");
            });
        map.Key(k =>
            {
                k.Column("KeyPart2");
            });
    }
    , ce => ce.OneToMany());
这将导致映射(去掉xml标记):

但我想我需要这个映射,包括两个关键部分:

<bag name="Childs">
  <key column="KeyPart1" />
  <key column="KeyPart2" />
  <one-to-many class="Child" />
</bag>

这是类的完整结构:

public class ParentIdentifier
{
    public virtual string KeyPart1 { get; set; }
    public virtual string KeyPart2 { get; set; }

    public override bool Equals(object obj)
    {
        if (obj == null)
            return false;
        var t = obj as ParentIdentifier;
        if (t == null)
            return false;
        if (KeyPart1 == t.KeyPart1 && KeyPart2 == t.KeyPart2)
            return true;
        return false;
    }

    public override int GetHashCode()
    {
        return (KeyPart1 + "|" + KeyPart2).GetHashCode();
    }

    public override string ToString()
    {
        return string.Format("KeyPart1 = {0}; KeyPart2 = {1}", KeyPart1, KeyPart2);
    }
}


[Serializable]
public class Parent
{
    #region Primary key

    public virtual ParentIdentifier Id { get; set; }

    #endregion Primary key

    public Parent()
    {
        Childs = new List<Child>();
    }

    public virtual IList<Child> Childs { get; set; }
}

public class ParentMap : ClassMapping<Parent>
{
    public ParentMap()
    {
        Table("Parent");

        ComponentAsId(
            x => x.Id,
            caim =>
            {
                caim.Property(x => x.KeyPart1, pm => 
                    {
                        pm.Column("KeyPart1");
                        pm.Length(20);
                    } );
                caim.Property(x => x.KeyPart2, pm => 
                    {
                        pm.Column("KeyPart2");
                        pm.Length(64);
                    } );
            });

        Bag(p => p.Childs,
            map =>
            {
                map.Key(k =>
                    {
                        k.Column("KeyPart1");
                    });
                map.Key(k =>
                    {
                        k.Column("KeyPart2");
                    });
            }
            , ce => ce.OneToMany());
    }
}

[Serializable]
public class Child
{
    #region Primary key

    public virtual int ChildId { get; set; }

    #endregion Primary key

    public virtual Parent Parent { get; set; }
}


public class ChildMap : ClassMapping<Child>
{
    public ChildMap()
    {
        Table("Child");

        Id(p => p.ChildId, 
            map => 
                {
                    map.Generator(Generators.Assigned);
                    map.Column("ChildId");
                });

        ManyToOne(p => p.Parent, 
            map => map.Columns(
                col1 => 
                {
                    col1.Name("KeyPart1");
                },
                col2 =>
                {
                    col2.Name("KeyPart2");
                }
                ));
    }
}
公共类父标识符
{
公共虚拟字符串KeyPart1{get;set;}
公共虚拟字符串KeyPart2{get;set;}
公共覆盖布尔等于(对象对象对象)
{
if(obj==null)
返回false;
var t=对象作为父标识符;
如果(t==null)
返回false;
if(KeyPart1==t.KeyPart1&&KeyPart2==t.KeyPart2)
返回true;
返回false;
}
公共覆盖int GetHashCode()
{
return(KeyPart1+“|”+KeyPart2.GetHashCode();
}
公共重写字符串ToString()
{
返回string.Format(“KeyPart1={0};KeyPart2={1}”,KeyPart1,KeyPart2);
}
}
[可序列化]
公共类父类
{
#区域主键
公共虚拟父标识符Id{get;set;}
#端域主键
公共家长()
{
Childs=新列表();
}
公共虚拟IList子项{get;set;}
}
公共类ParentMap:类映射
{
公共ParentMap()
{
表(“母公司”);
成分(
x=>x.Id,
caim=>
{
属性(x=>x.KeyPart1,pm=>
{
pm.列(“关键部分1”);
pm.长度(20);
} );
属性(x=>x.KeyPart2,pm=>
{
pm.栏(“关键部分2”);
pm.长度(64);
} );
});
袋子(p=>p.儿童,
地图=>
{
map.Key(k=>
{
k、 列(“关键部分1”);
});
map.Key(k=>
{
k、 列(“关键部分2”);
});
}
,ce=>ce.OneToMany());
}
}
[可序列化]
公营儿童
{
#区域主键
公共虚拟int ChildId{get;set;}
#端域主键
公共虚拟父级{get;set;}
}
公共类ChildMap:ClassMapping
{
公共儿童地图()
{
表(“儿童”);
Id(p=>p.ChildId,
地图=>
{
地图生成器(生成器已分配);
映射列(“ChildId”);
});
多酮(p=>p.父母,
map=>map.Columns(
col1=>
{
col1.名称(“关键部分1”);
},
col2=>
{
col2.名称(“关键部分2”);
}
));
}
}

因为您要调用map.Key(…)两次,所以第二个会覆盖第一个!你应该打电话:

map.Key(k =>
        {
            k.Columns(
                c1 => c1.Name("c1"),
                c2 => c2.Name("c2") /*as many as you want*/
            );
        });
public class ParentIdentifier
{
    public virtual string KeyPart1 { get; set; }
    public virtual string KeyPart2 { get; set; }

    public override bool Equals(object obj)
    {
        if (obj == null)
            return false;
        var t = obj as ParentIdentifier;
        if (t == null)
            return false;
        if (KeyPart1 == t.KeyPart1 && KeyPart2 == t.KeyPart2)
            return true;
        return false;
    }

    public override int GetHashCode()
    {
        return (KeyPart1 + "|" + KeyPart2).GetHashCode();
    }

    public override string ToString()
    {
        return string.Format("KeyPart1 = {0}; KeyPart2 = {1}", KeyPart1, KeyPart2);
    }
}


[Serializable]
public class Parent
{
    #region Primary key

    public virtual ParentIdentifier Id { get; set; }

    #endregion Primary key

    public Parent()
    {
        Childs = new List<Child>();
    }

    public virtual IList<Child> Childs { get; set; }
}

public class ParentMap : ClassMapping<Parent>
{
    public ParentMap()
    {
        Table("Parent");

        ComponentAsId(
            x => x.Id,
            caim =>
            {
                caim.Property(x => x.KeyPart1, pm => 
                    {
                        pm.Column("KeyPart1");
                        pm.Length(20);
                    } );
                caim.Property(x => x.KeyPart2, pm => 
                    {
                        pm.Column("KeyPart2");
                        pm.Length(64);
                    } );
            });

        Bag(p => p.Childs,
            map =>
            {
                map.Key(k =>
                    {
                        k.Column("KeyPart1");
                    });
                map.Key(k =>
                    {
                        k.Column("KeyPart2");
                    });
            }
            , ce => ce.OneToMany());
    }
}

[Serializable]
public class Child
{
    #region Primary key

    public virtual int ChildId { get; set; }

    #endregion Primary key

    public virtual Parent Parent { get; set; }
}


public class ChildMap : ClassMapping<Child>
{
    public ChildMap()
    {
        Table("Child");

        Id(p => p.ChildId, 
            map => 
                {
                    map.Generator(Generators.Assigned);
                    map.Column("ChildId");
                });

        ManyToOne(p => p.Parent, 
            map => map.Columns(
                col1 => 
                {
                    col1.Name("KeyPart1");
                },
                col2 =>
                {
                    col2.Name("KeyPart2");
                }
                ));
    }
}
map.Key(k =>
        {
            k.Columns(
                c1 => c1.Name("c1"),
                c2 => c2.Name("c2") /*as many as you want*/
            );
        });