Nhibernate复合关键问题

发布于 2024-10-21 19:28:59 字数 676 浏览 5 评论 0原文

我有一个名为 person_skills 的表,如下所示:

person_id、skill_type_id、base_score、misc_score

有一个查找表,其中包含 Skill_types 的 id、名称。

现在棘手的是我有一个 person_id、skill_type_id 的复合键。由于一个人可能拥有 5 种技能,因此该表中会有很多条目。

目前我有一个像这样的类:

public class skill 
{
    int BaseScore {get;set;}
    int MiscScore {get;set;}
}

然后我有一个类来包含所有这些,如下所示:

public class person_skills
{
    int person_id {get;set;}
    IDictionary<skill_type, skill> skills {get;set;}
}

现在我不确定这是否是处理这种关系的最佳方式,最终我需要能够为人们提供技能的链接,一人多才。

我正在考虑只放入一个自动递增 id 列并将其用作 PK,但这似乎并不理想。如果需要,我可以更改模型和数据库,但由于这是在页面的 ajax 部分中使用的,所以我需要能够更改技能,然后将它们更新到数据库中。

I have a table called person_skills like so:

person_id, skill_type_id, base_score, misc_score

There is a lookup table that contains id, name for skill_types.

Now the tricky thing is that I have a composite key for person_id, skill_type_id. There will be many entries within this table as a person may have 5 skills.

Currently I have got a class like so:

public class skill 
{
    int BaseScore {get;set;}
    int MiscScore {get;set;}
}

Then I have a class to contain all this like below:

public class person_skills
{
    int person_id {get;set;}
    IDictionary<skill_type, skill> skills {get;set;}
}

Now im not sure if this is the best way to handle this relationship, ultimately I need to be able to give people a link to skills, there is one person to many skills.

I was thinking about just putting in an auto incrememnt id column and use that as the PK, but it doesn't seem ideal. I can change the models and the DB if required, but as this is used within an ajax part of a page I need to be able to change the skills and then update them into the database.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

乖乖公主 2024-10-28 19:28:59

我没有找到实际的问题,但无论如何我都会回答。 :)

您不需要 person_skills 表的代理键。您的复合键由 person_id 和 Skill_type_id 组成,应该足够了。我相信以下类和映射反映了您在这里想要完成的任务。

类:

public class Person
{
    public virtual int PersonId { get; set; }
    public virtual String Name { get; set; }
    public virtual IList<PersonSkills> Skills { get; set; }
}

public class SkillType
{
    public virtual int SkillTypeId { get; set; }
    public virtual String SkillName { get; set; }
    public virtual IList<PersonSkills> Persons { get; set; }       
}

public class PersonSkills
{
    public virtual int PersonId { get; set; }
    public virtual int SkillTypeId { get; set; }
    public virtual int BaseScore { get; set; }
    public virtual int MiscScore { get; set; }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(this, obj))
        {
            return true;
        }

        if (obj == null || !(obj is PersonSkills))
        {
            return false;
        }
        PersonSkills o = obj as PersonSkills;

        return (this.PersonId == o.PersonId
            && this.SkillTypeId == o.SkillTypeId);
    }

    public override int GetHashCode()
    {
        int hash = 13;
        hash = hash + this.PersonId.GetHashCode();
        hash = hash + this.SkillTypeId.GetHashCode();
        return hash;
    }
}

映射:(FluentNhibernate)

public class PersonMap : ClassMap<Person>
{
    public PersonMap()
    {
        Id(x => x.PersonId);
        Map(x => x.Name);
        HasMany(x => x.Skills)
            .KeyColumn("PersonId")
            .Cascade.All();
    }
}

public class SkillTypeMap : ClassMap<SkillType>
{
    public SkillTypeMap()
    {
        Id(x => x.SkillTypeId);
        Map(x => x.SkillName);
        HasMany(x => x.Persons)
            .KeyColumn("SkillTypeId")
          .Cascade.All();
    }
}

public class PersonSkillsMap : ClassMap<PersonSkills>
{
    public PersonSkillsMap()
    {
        CompositeId()
            .KeyProperty(x => x.PersonId)
            .KeyProperty(x => x.SkillTypeId);
        Map(x => x.BaseScore);
        Map(x => x.MiscScore);
    }
}

映射(hbm,由 FluentNHibernate 生成 - 我删除了不需要的输出):

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" >
  <class xmlns="urn:nhibernate-mapping-2.2" name="Person" table="Person">
    <id name="PersonId" type="int">
      <column name="PersonId" />
      <generator class="identity" />
    </id>
    <bag cascade="all" name="Skills" mutable="true">
      <key>
        <column name="PersonId" />
      </key>
      <one-to-many class="PersonSkills" />
    </bag>
    <property name="Name" type="String">
      <column name="Name" />
    </property>
  </class>
</hibernate-mapping>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" >
  <class xmlns="urn:nhibernate-mapping-2.2" name="SkillType" table="SkillType">
    <id name="SkillTypeId" type="int">
      <column name="SkillTypeId" />
      <generator class="identity" />
    </id>
    <bag cascade="all" name="Persons">
      <key>
        <column name="SkillTypeId" />
      </key>
      <one-to-many class="PersonSkills" />
    </bag>
    <property name="SkillName" type="String">
      <column name="SkillName" />
    </property>
  </class>
</hibernate-mapping>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" >
  <class xmlns="urn:nhibernate-mapping-2.2" name="PersonSkills" table="PersonSkills">
    <composite-id mapped="false" unsaved-value="undefined">
      <key-property name="PersonId" type="int">
        <column name="PersonId" />
      </key-property>
      <key-property name="SkillTypeId" type="int">
        <column name="SkillTypeId" />
      </key-property>
    </composite-id>
    <property name="BaseScore" type="int">
      <column name="BaseScore" />
    </property>
    <property name="MiscScore" type="int">
      <column name="MiscScore" />
    </property>
  </class>
</hibernate-mapping>

I did not find an actual question but I'll answer anyway. :)

You do not need a surrogate key for the person_skills table. Your composite key, consisting of person_id and skill_type_id, should be sufficient. I believe the following classes and mappings reflect what you are trying to accomplish here.

Classes:

public class Person
{
    public virtual int PersonId { get; set; }
    public virtual String Name { get; set; }
    public virtual IList<PersonSkills> Skills { get; set; }
}

public class SkillType
{
    public virtual int SkillTypeId { get; set; }
    public virtual String SkillName { get; set; }
    public virtual IList<PersonSkills> Persons { get; set; }       
}

public class PersonSkills
{
    public virtual int PersonId { get; set; }
    public virtual int SkillTypeId { get; set; }
    public virtual int BaseScore { get; set; }
    public virtual int MiscScore { get; set; }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(this, obj))
        {
            return true;
        }

        if (obj == null || !(obj is PersonSkills))
        {
            return false;
        }
        PersonSkills o = obj as PersonSkills;

        return (this.PersonId == o.PersonId
            && this.SkillTypeId == o.SkillTypeId);
    }

    public override int GetHashCode()
    {
        int hash = 13;
        hash = hash + this.PersonId.GetHashCode();
        hash = hash + this.SkillTypeId.GetHashCode();
        return hash;
    }
}

Mappings: (FluentNhibernate)

public class PersonMap : ClassMap<Person>
{
    public PersonMap()
    {
        Id(x => x.PersonId);
        Map(x => x.Name);
        HasMany(x => x.Skills)
            .KeyColumn("PersonId")
            .Cascade.All();
    }
}

public class SkillTypeMap : ClassMap<SkillType>
{
    public SkillTypeMap()
    {
        Id(x => x.SkillTypeId);
        Map(x => x.SkillName);
        HasMany(x => x.Persons)
            .KeyColumn("SkillTypeId")
          .Cascade.All();
    }
}

public class PersonSkillsMap : ClassMap<PersonSkills>
{
    public PersonSkillsMap()
    {
        CompositeId()
            .KeyProperty(x => x.PersonId)
            .KeyProperty(x => x.SkillTypeId);
        Map(x => x.BaseScore);
        Map(x => x.MiscScore);
    }
}

Mappings (hbm, generated by FluentNHibernate - I removed output that is not required):

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" >
  <class xmlns="urn:nhibernate-mapping-2.2" name="Person" table="Person">
    <id name="PersonId" type="int">
      <column name="PersonId" />
      <generator class="identity" />
    </id>
    <bag cascade="all" name="Skills" mutable="true">
      <key>
        <column name="PersonId" />
      </key>
      <one-to-many class="PersonSkills" />
    </bag>
    <property name="Name" type="String">
      <column name="Name" />
    </property>
  </class>
</hibernate-mapping>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" >
  <class xmlns="urn:nhibernate-mapping-2.2" name="SkillType" table="SkillType">
    <id name="SkillTypeId" type="int">
      <column name="SkillTypeId" />
      <generator class="identity" />
    </id>
    <bag cascade="all" name="Persons">
      <key>
        <column name="SkillTypeId" />
      </key>
      <one-to-many class="PersonSkills" />
    </bag>
    <property name="SkillName" type="String">
      <column name="SkillName" />
    </property>
  </class>
</hibernate-mapping>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" >
  <class xmlns="urn:nhibernate-mapping-2.2" name="PersonSkills" table="PersonSkills">
    <composite-id mapped="false" unsaved-value="undefined">
      <key-property name="PersonId" type="int">
        <column name="PersonId" />
      </key-property>
      <key-property name="SkillTypeId" type="int">
        <column name="SkillTypeId" />
      </key-property>
    </composite-id>
    <property name="BaseScore" type="int">
      <column name="BaseScore" />
    </property>
    <property name="MiscScore" type="int">
      <column name="MiscScore" />
    </property>
  </class>
</hibernate-mapping>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文