繁体   English   中英

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

[英]Confusion using CompositeId / Composite Keys in Fluent NHibernate

请有人可以解释NHibernate中的复合ID如何工作吗?

我想我缺少了一些东西。 这就是我在做什么。

我有一个TeamMember类,称为TeamMemberUnified,因为我试图将两个不同的数据库与视图链接起来以创建一个统一的数据库。 每个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();
    }
}

这是TeamMember的地图

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])”}}

例如,复合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))来代替主键作为Just ID,因为如果仅使用学生ID,则会看到两个Jons,但是如果使用( ID,StudentID),我们将获得唯一的标识符,只有一行ID为1的学生和学生ID为10023的学生。 希望这可以帮助。 因此,最后您可能有两个或多个带有重复值的色散,但这些列在一起可能未必具有唯一值。 希望这可以帮助。 抱歉,这张桌子看起来有些古怪。

供参考,现在正在工作。

这是主键上的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();

暂无
暂无

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

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