Отображение коллекции "один ко многим" с внешним ключом на внешний ключ

Я сопоставляю устаревшую базу данных с помощью 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>

Когда я запускаю отображение, я получаю несоответствие типа идентификатора, предполагая, что оно пытается вставить код формы в идентификатор вопроса. К сожалению, я не могу изменить структуру таблицы, и я не знаю, как это отобразить, и любая помощь будет принята с благодарностью.

2 ответа

Решение

Ваши отношения - это отношения m:n без промежуточной сущности. Классическая ошибка - определять отношения m:n таким образом, потому что она обрезает сторону pk, что приводит к ситуации, когда есть две таблицы с одинаковым атрибутом / полем, и они семантически представляют одну и ту же вещь. Однако, поскольку они не являются значениями pk в обеих сторонах, существует избыточность и возможная неточность. Вы можете соединить две таблицы вместе по двум полям, но семантически это ничего не значит: для модели сущности, чтобы связать сущность X с Y, сторона FK получает сторону PK отношения как поля FK, а для отношений m:n вы нужны два отношения m:1, происходящие из промежуточного объекта. Вот и все, нет исключения.

Поэтому, хотя вы хотите отобразить это так, как вы предлагаете, это не может быть сделано, так как o/r mapper не может гарантировать правильность, потому что предложенные отношения просто не верны.

Ну, это "проблема" с ОРМ. Я говорю "проблема", потому что Hibernate технически корректен: внешние ключи должны быть первичными ключами. Но, как вы видите, это не всегда так.

ID на самом деле используется для чего-либо? Если нет, путь наименьшего сопротивления должен сделать FormCode первичным ключом. Это вариант?

Если нет, я действительно не уверен, что делать, кроме как задавать вопросы, а не рассматривать их как дочерние объекты.

Другие вопросы по тегам