Nhibernate 将具有外键的一对多集合映射到外键

Nhibernate 将具有外键的一对多集合映射到外键,nhibernate,nhibernate-mapping,legacy-database,Nhibernate,Nhibernate Mapping,Legacy Database,我正在用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

我正在用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)  
<?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>
两个表之间的关系是formcode列

我当前的映射是这样的

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)  
<?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>

当我运行映射时,我得到一个标识符类型不匹配,假设它试图将formcode放入问题的Id中。不幸的是,我无法更改表的结构,我不知道如何映射它,非常感谢您的帮助。

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

身份证真的有什么用吗?如果不是,那么阻力最小的方法就是将FormCode作为主键。这是一种选择吗


如果没有,我真的不知道除了查询问题,而不是将它们作为子实体来处理,该怎么办。

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

身份证真的有什么用吗?如果不是,那么阻力最小的方法就是将FormCode作为主键。这是一种选择吗


如果不是,我真的不知道该怎么做,除了查询问题,而不是将它们作为子实体处理。

您的关系是没有中间实体的m:n关系。以这种方式定义m:n关系是一个典型的错误,因为它切断了pk端,这导致了两个表具有相同的属性/字段,并且它们恰好在语义上表示相同的东西。然而,由于它们在两侧都是非pk值,因此可能存在冗余和不准确。您可以通过两个字段将两个表连接在一起,但从语义上讲,这并不意味着什么:对于实体模型来说,将实体X关联到Y,FK端将关系的PK端作为FK字段,而对于m:n关系,您需要两个源自中间实体的m:1关系。就这样,没有例外


因此,尽管您希望以您建议的方式映射此关系,但这无法实现,因为o/r映射器无法保证正确性,因为建议的关系根本不正确。

您的关系是一个没有中间实体的m:n关系。以这种方式定义m:n关系是一个典型的错误,因为它切断了pk端,这导致了两个表具有相同的属性/字段,并且它们恰好在语义上表示相同的东西。然而,由于它们在两侧都是非pk值,因此可能存在冗余和不准确。您可以通过两个字段将两个表连接在一起,但从语义上讲,这并不意味着什么:对于实体模型来说,将实体X关联到Y,FK端将关系的PK端作为FK字段,而对于m:n关系,您需要两个源自中间实体的m:1关系。就这样,没有例外


因此,尽管您希望以您建议的方式映射此关系,但无法做到这一点,因为o/r映射器无法保证正确性,因为建议的关系根本不正确。

谢谢您的回复。我担心情况可能是这样。需要返回到客户端,看看是否可以稍微更改数据库的结构。再次感谢您的回答-1当一个问题只能在一份问卷中时,它怎么可能是M:N?@cletus:这两个表可以通过FormCode连接起来,因为这是两个表之间的关系属性,这意味着结果集可以产生一个本质上是M:N的集,因为并不是说对于问卷中的每个FormCode,有1个表单代码有问题。谢谢你的回复。我担心情况可能是这样。需要返回到客户端,看看是否可以稍微更改数据库的结构。再次感谢您的回答-1当一个问题只能在一份问卷中时,它怎么可能是M:N?@cletus:这两个表可以通过FormCode连接起来,因为这是两个表之间的关系属性,这意味着结果集可以产生一个本质上是M:N的集,因为并不是说对于问卷中的每个FormCode,有1个表单代码有问题。谢谢你的回复。我将回到客户机,看看是否可以让他们更改他们的模式。再次感谢您的回复,您不必更改您的模式。告诉Hibernate PK是FormCode就足够了,即使它不是。谢谢你的回复。我将回到客户机,看看是否可以让他们更改他们的模式。再次感谢您的回复,您不必更改您的模式。告诉Hibernate PK是FormCode就足够了,即使它不是。