我正在使用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中。不幸的是我无法改变表格的结构,我对如何映射这一点感到茫然,我们将非常感谢任何帮助。
答案 0 :(得分:4)
您的关系是m:n关系,没有中间实体。以这种方式定义m:n关系是一个经典的错误,因为它会切出一个pk端,这会导致两个表具有相同属性/字段的情况,并且它们恰好在语义上代表相同的事物。但是,因为它们在双方都是非pk值,所以存在冗余并且还可能存在不准确性。您可以在两个字段上将两个表连接在一起,但在语义上它没有任何意义:对于将实体X与Y关联的实体模型,FK端将关系的PK侧作为FK字段获取,对于m:n关系,您需要两个m:1关系来自中间实体。那是它,也不例外。
因此,虽然你想以你的方式映射这个,但是由于o / r映射器无法保证正确性,因此无法完成,因为建议的关系根本不正确。
答案 1 :(得分:2)
这是ORM的“问题”。我说“问题”是因为Hibernate在技术上是正确的:外键应该是主键。但是,正如你所见,情况并非总是如此。
ID实际上是用于什么吗?如果不是,阻力最小的路径是使FormCode成为主键。这是一个选择吗?
如果没有,除了查询问题而不是将它们视为子实体之外,我真的不确定该做什么。