【问题标题】:Confusion using CompositeId / Composite Keys in Fluent NHibernate在 Fluent NHibernate 中使用 CompositeId / Composite Keys 的困惑
【发布时间】:2015-11-12 16:47:32
【问题描述】:

请有人解释一下复合 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");
    }
}

虽然 TeamRole 与此类映射。 RoleId 是一个唯一的 Id,但现在我已经在一个视图中“合并”了两个数据库中的两个数据库/引用的表,RoleId 仅在每个 Db 的行中是唯一的。 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");
    }
}

我的理解是我需要在 TeamRole 上定义一个复合 Id 来定义如何唯一标识行。

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

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

【问题讨论】:

    标签: c# sql-server nhibernate fluent


    【解决方案1】:

    例如,复合 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。在那里,我们必须创建一个复合键。因此,我们需要使用复合主键而不是 Just ID,而是使用复合主键,即 (ID,StudentID) 因为如果我们只使用学生 ID,您会看到我们会得到两个 Jons,但如果我们使用 ( ID,StudentID) 我们会得到一个唯一的标识符,只有一行 ID 1 和学生 ID 10023 在一起。希望这可以帮助。因此,最后您可能有两个或多个具有重复值的列,但这些列一起可能没有唯一的值。希望这可以帮助。抱歉,如果表格看起来有点不稳定。

    【讨论】:

    • 感谢 Wes,这与我对这个词的理解非常相似。我想我应该提出复合键如何在 NHibernate 中工作的问题。抱歉,我已经更新了我的帖子标题。
    • 我很高兴它有帮助。对不起,我出去了,我无法回应。我对NHibernate一无所知。看起来你可能会遇到问题。
    【解决方案2】:

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

    这是主键上的 TeamRole 映射(一对多的一侧):

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

    【讨论】:

      猜你喜欢
      • 2014-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-30
      • 2015-05-07
      • 2023-04-01
      相关资源
      最近更新 更多