C# 在Fluent NHibernate中使用CompositeId/Composite键的混淆

C# 在Fluent NHibernate中使用CompositeId/Composite键的混淆,c#,sql-server,nhibernate,fluent,C#,Sql Server,Nhibernate,Fluent,有人能解释一下复合ID在NHibernate中是如何工作的吗 我想我错过了什么。这就是我正在做的 我有一个名为TeamMemberUnified的TeamMember类,因为我试图用视图链接两个不同的数据库,以创建一个统一的数据库。每个TeamMember实例都与一个人在建筑中扮演的角色相关 public class TeamMemberUnified: DataItem { public virtual int Id { get; set; } // person / con

有人能解释一下复合ID在NHibernate中是如何工作的吗

我想我错过了什么。这就是我正在做的

我有一个名为TeamMemberUnified的TeamMember类,因为我试图用视图链接两个不同的数据库,以创建一个统一的数据库。每个TeamMember实例都与一个人在建筑中扮演的角色相关

public class TeamMemberUnified: DataItem
{
    public virtual int Id { get; set; }

    // person / contact details
    public virtual byte[] ContactId { get; set; }
    public virtual Contact Contact { get; set; }        

    /// property id 
    public virtual string PropIdUnified { get; set; }
    public virtual string UnifiedDbCode { get; set; }            
    public virtual int RoleId { get; set; }

    // role the person plays at this property
    public virtual TeamRoleUnified TeamRole { get; set; }
}
人员在建筑物中扮演的角色由TeamRole类表示。几乎是静态数据/查找类

public class TeamRoleUnified: DataItem
{
    public virtual int RoleId { get; set; }
    public virtual string Title{ get; set; }
    public virtual string UnifiedDbCode { get; set; }

    public override bool Equals(object obj)
    {
        if (obj == null || GetType() != obj.GetType())
        {
            return false;
        }

        var that = (TeamRoleUnified)obj;

        return this.RoleId == that.RoleId &&
            this.UnifiedDbCode == that.UnifiedDbCode;
    }

    public override int GetHashCode()
    {
        return RoleId.GetHashCode() ^
            UnifiedDbCode.GetHashCode();
    }
}
这是团队成员的地图

public class TeamMemberUnifiedMap : ClassMap<TeamMemberUnified>
{
    public TeamMemberUnifiedMap()
    {
        Id(x => x.Id, "Id");
        Map(x => x.ContactId);
        Map(x => x.PropIdUnified);
        Map(x => x.UnifiedDbCode);

        // team member has one role at this building
        References(t => t.TeamRole)
           .Columns(new string[] {"RoleId", "UnifiedDbCode"});

        Table("dbo.TeamMembers");
    }
}
公共类TeamMemberUnifiedMap:ClassMap
{
公共团队成员UnifiedMap()
{
Id(x=>x.Id,“Id”);
Map(x=>x.ContactId);
Map(x=>x.0);
Map(x=>x.UnifiedDbCode);
//团队成员在该建筑中扮演一个角色
引用(t=>t.TeamRole)
.Columns(新字符串[]{“RoleId”,“UnifiedDbCode”});
表(“dbo.TeamMembers”);
}
}
而TeamRole则映射到此类。RoleId是唯一的Id,但现在我在一个视图中“合并”了两个数据库/引用了两个数据库中的表。RoleId仅在每个数据库的行中是唯一的。Db由UnifiedDbCode限定

public class TeamRoleUnifiedMap : ClassMap<TeamRoleUnified>
{
    public TeamRoleUnifiedMap()
    {
        CompositeId()
            .KeyProperty(x => x.RoleId)
            .KeyProperty(x => x.UnifiedDbCode);

        //References(x => x.)

        Map(x => x.RoleId);
        Map(x => x.Title);
        Map(x => x.UnifiedDbCode);

        Table("dbo.TeamRoles");
    }
}
public类TeamRoleUnifiedMap:ClassMap
{
公共团队角色eunifiedmap()
{
复合ID()
.KeyProperty(x=>x.RoleId)
.KeyProperty(x=>x.UnifiedDbCode);
//参考文献(x=>x.)
Map(x=>x.RoleId);
地图(x=>x.Title);
Map(x=>x.UnifiedDbCode);
表(“dbo.TeamRoles”);
}
}
我的理解是,我需要在TeamRole上定义一个复合Id,以定义行的唯一标识方式

但是,当我尝试运行代码时,会出现以下错误:

{“外键(FK8FB93FCE3B0D5D3E:dbo.TeamMembers[RoleId]))
必须与引用的主键(dbo.TeamRoles[RoleId,UnifiedDbCode])”具有相同的列数。

例如,复合ID是包含多个部分的主键。假设我们有一张桌子:

|ID|StudentID|Name|Class|
-------------------------
|1 |10023    |Jon |FR   |
|1 |10024    |Bob |FR   |
|2 |10023    |Jon |SO   |
|3 |12234    |Joe |FR   |

在本例中,假设您只想选择Jon,但出于某些原因,Jon和Bob的ID为1,这并不是唯一标识Jon的。因此,我们必须创建一个复合密钥。因此,我们需要使用复合主键,即(ID,StudentID),而不是一个ID,因为如果我们只使用学生ID,你会看到我们会得到两个Jon,但是如果我们使用(ID,StudentID)的复合键,我们会得到一个唯一标识符,只有一行ID为1,学生ID为10023。希望这有帮助。因此,最终可能会有两个或更多具有重复值的colun,但这些列一起可能没有uniqe值。希望这有帮助。如果桌子看起来有点不稳,很抱歉。

作为参考,现在可以使用了

这是主键上的团队角色映射(一对多的一侧):

这是外键映射(一对多的多方面):


谢谢韦斯,这与我对这个词的理解非常相似。我想我应该用措辞回答这个问题,复合键在NHibernate中是如何工作的。很抱歉造成混乱,我现在已经更新了我的帖子标题。我很高兴这有帮助。很抱歉,我出去了,无法回复。我对NHibernate一无所知。看来如果你真的这么做了,你可能会被绞死。
  CompositeId()
     .KeyProperty(x => x.RoleId)
     .KeyProperty(x => x.UnifiedDbCode);
  // team member has one role at this building
       References(t => t.TeamRole)
           .ForeignKey("TeamRoleFK")                                
           .Columns(new string[] {"RoleId", "UnifiedDbCode"})
           .Not.Update()
           .Not.Insert();