简体   繁体   English

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

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

Please can someone explain how composite Ids work in NHibernate? 请有人可以解释NHibernate中的复合ID如何工作吗?

I think I am missing something. 我想我缺少了一些东西。 This is what I am doing. 这就是我在做什么。

I have a TeamMember class, called TeamMemberUnified because I am trying to link two different databases with views to create a unified database. 我有一个TeamMember类,称为TeamMemberUnified,因为我试图将两个不同的数据库与视图链接起来以创建一个统一的数据库。 Each TeamMember instance relates to the role a person plays at a building. 每个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; }
}

The role a person plays at a building is represented by the TeamRole class. 一个人在建筑物中扮演的角色由TeamRole类表示。 Pretty much static data / a lookup class 几乎所有静态数据/查找类

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

This is the map for TeamMember 这是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");
    }
}

While the TeamRole is mapped with this class. 而TeamRole与此类映射。 The RoleId was a unique Id, but now I have "merged" two databases / referenced tables from two dbs in one view the RoleId is only unique within rows from each Db. RoleId是一个唯一的ID,但是现在我已经在一个视图中“合并”了两个数据库中的两个数据库/引用表,因此RoleId仅在每个Db的行中是唯一的。 The Db is qualified by the UnifiedDbCode. 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");
    }
}

My understanding is that I need to define a composite Id on the TeamRole to define how a row is uniquely identified. 我的理解是,我需要在TeamRole上定义一个复合ID,以定义如何唯一标识行。

However when I try to run the code I get this error: 但是,当我尝试运行代码时,出现此错误:

{"Foreign key (FK8FB93FCE3B0D5D3E:dbo.TeamMembers [RoleId])) must have same number of columns as the referenced primary key (dbo.TeamRoles [RoleId, UnifiedDbCode])"} {“外键(FK8FB93FCE3B0D5D3E:dbo.TeamMembers [RoleId]))必须具有与引用的主键相同的列数(dbo.TeamRoles [RoleId,UnifiedDbCode])”}}

A composite ID is a primary jey with multiple parts for example. 例如,复合ID是具有多个部分的主界面。 Lets say we have a table: 假设我们有一张桌子:

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

In this case lets say you want to select Jon only, but for some reson JOn and Bob have an ID of 1 and that isn't uniquely identifying Jon alone. 在这种情况下,假设您只想选择Jon,但是对于某些共振点,JOn和Bob的ID为1,这并不能唯一地标识Jon。 There for we have to create a composite key. 在那里,我们必须创建一个复合键。 So instead of a primary key being Just ID we need to use the composite primary key which would be the (ID,StudentID) Because if we just used the Student ID you see we would get two Jons but if we use the composite key of (ID,StudentID) we would get a unique identifier there is only one row with ID 1 and Student ID 10023 together. 因此,我们需要使用复合主键(即(ID,StudentID))来代替主键作为Just ID,因为如果仅使用学生ID,则会看到两个Jons,但是如果使用( ID,StudentID),我们将获得唯一的标识符,只有一行ID为1的学生和学生ID为10023的学生。 Hope this helps. 希望这可以帮助。 So in the end you may have a two or more coluns with repeating values but those columns together may not have a uniqe value together. 因此,最后您可能有两个或多个带有重复值的色散,但这些列在一起可能未必具有唯一值。 Hope this helps. 希望这可以帮助。 Sorry if the table looks a little wonky. 抱歉,这张桌子看起来有些古怪。

For reference, this is working now. 供参考,现在正在工作。

This is the TeamRole Mapping on the Primary Key (The One side of the one-to-many): 这是主键上的TeamRole映射(一对多的一侧):

  CompositeId()
     .KeyProperty(x => x.RoleId)
     .KeyProperty(x => x.UnifiedDbCode);

This is the Foreign key mapping (The Many side of the one-to-many): 这是外键映射(一对多的多面):

  // 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