1

我正在使用 nhibernate 映射旧数据库,并且在映射关系时遇到了一些问题。

这两个类看起来像这样

public class Questionnaire
{
    public int Id {get; set;}
    public string FormCode {get; set;}
    public IList<Question> Questions {get; set;}
}

public class Question
{
    public int Id{get; set;}
    public Questionnaire Questionnaire {get;set;}
    public string QuestionText{get;set;}
}

像这样的表

Questionnaire Table  
Id int  
FormCode varchar(100)  

Question Table  
Id int  
FormCode varchar(100)  
QuestionText varchar(max)  

两个表之间的关系是 formcode 列。

我现在的映射是这样的

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="QDesign.Core.Models" assembly="QDesign.Core">
<class name="Questionnaire" table="_questionnaire_list">
    <id column="Id" name="Id">
            <generator class="identity"/>
    </id>
        <property name="FormCode" column="FormCode"/>
        <bag name="Questions" >
            <key foreign-key="FormCode" property-ref="FormCode" />
            <one-to-many class="Question" />            
        </bag>
</class>
</hibernate-mapping>

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="QDesign.Core.Models" assembly="QDesign.Core">
<class name="Question" table="_questionnaire_items">
    <id column="ID" name="Id" unsaved-value="-1">
            <generator class="identity" />
        </id>
        <property name="QuestionText" column="QuestionText" />
</class>
</hibernate-mapping>

当我运行映射时,假设它试图将表单代码放入问题的 ID 中,我得到一个标识符类型不匹配。不幸的是,我无法更改表格的结构,我不知道如何映射它,任何帮助将不胜感激。

4

2 回答 2

4

您的关系是没有中间实体的 m:n 关系。以这种方式定义 m:n 关系是一个典型的错误,因为它切除了一个 pk 端,这导致存在两个具有相同属性/字段的表并且它们恰好在语义上表示相同事物的情况。但是,因为它们在双方都是非 pk 值,所以存在冗余和不准确的可能。您可以通过两个字段将两个表连接在一起,但在语义上它没有任何意义:对于将实体 X 与 Y 相关联的实体模型,FK 端将关系的 PK 端作为 FK 字段,而对于 m:n 关系,您需要两个源自中间实体的 m:1 关系。就是这样,没有例外。

因此,尽管您想按照您建议的方式进行映射,但由于 o/r 映射器无法保证正确性,因为建议的关系根本不正确,因此无法完成。

于 2009-02-08T10:38:35.387 回答
2

这就是 ORM 的“问题”。我说“问题”是因为 Hibernate 在技术上是正确的:外键应该是主键。但是,正如你所看到的,情况并非总是如此。

ID实际上用于任何事情吗?如果没有,阻力最小的路径是使 FormCode 成为主键。这是一个选择吗?

如果不是,我真的不确定除了查询问题而不是将它们视为子实体之外还能做什么。

于 2009-02-08T03:44:24.320 回答