Свободное отображение NHibernate Словарь самообращения - PullRequest
0 голосов
/ 02 апреля 2012

Я понимаю, что есть несколько связанных вопросов, и я рассмотрел многие из них, но решения, похоже, не работают в моем случае.

Я использую NH 2.1 с Fluent (да, это более старая версия, но это общий знаменатель в нескольких смежных проектах, и для ее обновления потребуется определенная работа), и я в основном картирую FSM; Пользователю этой системы задаются вопросы, по одному за раз, на которые обычно есть два или более ответов, из которых они выбирают. Их ответ приводит к следующему вопросу, который может варьироваться в зависимости от данного ответа.

Это создает домен примерно так (слегка очищенный):

public class Question
{
    public virtual int Id { get; set; }

    /// <summary>
    /// Gets or sets the "questionnaire" Template in which this Question is asked.
    /// </summary>
    /// <value>The template.</value>
    public virtual QuestionnaireTemplate Template { get; set; }

    /// <summary>
    /// Gets or sets a string to be displayed to the user containing the question to answer.
    /// </summary>
    /// <value>The question.</value>
    public virtual string QuestionText { get; set; }

    /// <summary>
    /// Gets or sets a Question representing the previous question in the questionnaire.
    /// </summary>
    /// <value>The previous question.</value>
    public virtual Question PreviousQuestion { get; set; }

    /// <summary>
    /// Gets or sets a Dictionary of Questions, each representing the question that should follow given a specified answer to the current question.
    /// Null Values for Keys in this Dictionary represent endpoints of the questionnaire.
    /// </summary>
    /// <value>The next questions.</value>
    public virtual IDictionary<string, Question> NextQuestions { get; set; }
}

Итак, домен требуется для создания таблицы с самообращением; простой внешний ключ к предыдущему вопросу и таблица «Вопросы-ответы» «многие-ко-многим» с ключами «Вопрос-ответ», содержащая ключ следующего вопроса, который нужно задать, учитывая конкретный ответ на текущий вопрос.

Вот мое отображение, основанное, по крайней мере, на одном ответе на связанный с ним вопрос о сопоставлении словаря:

public TourQuestionMap()
    {
        Id(x => x.Id);
        References(x => x.Template);
        Map(x => x.QuestionText);

        References(x => x.PreviousQuestion);
        HasManyToMany(x => x.NextQuestions)
            .Table("QuestionAnswers")
            .ParentKeyColumns.Add("QuestionId", "Answer")
            .ChildKeyColumn("NextQuestionId")
            .AsMap("Answer")
            .Cascade.All();
    }

... но когда я пытаюсь экспортировать схему, основанную на этом, я получаю ошибку, касающуюся ассоциации с не отображенной сущностью KeyValuePair, которая указывает на то, что я пытаюсь использовать неправильную конструкцию коллекции в NH. У меня недостаточно опыта в сопоставлении коллекций, кроме базовых сопоставлений HasMany () другого сопоставленного объекта.

Вот базовая схема, которую я ищу:

Question
   QuestionId (int, PK, non-nullable)
   TemplateId (int, FK to Template, not nullable, not an issue AFAIK)
   QuestionText (string, not nullable)
   PreviousQuestion (int, FK to Question, nullable, also not an issue AFAIK)

QuestionAnswer (my problem child)
   QuestionId (int, PK, FK to Question, not nullable)
   Answer (string PK, key of Dictionary in domain, not nullable)
   NextQuestionId (int, FK to Question, nullable)

1 Ответ

1 голос
/ 02 апреля 2012

Можете ли вы определить Ответ отдельно и предоставить для него сопоставление?

Что-то вроде

class Answer
{
  public virtual int Id { get; set; }
  public virtual string AnswerText { get; set; }
  public virtual Question NextQuestion { get; set; }
}

Теперь вопрос становится

class Question
{
    public virtual int Id { get; set; }
    public virtual QuestionnaireTemplate Template { get; set; }
    public virtual string QuestionText { get; set; }
    public virtual Question PreviousQuestion { get; set; }
    private List<Answer> answers
    //Map this
    public virtual IList<Answer> AnswerList { get return answers; }
    public virtual IDictionary<string, Answer> Answers {get return answers.ToDictionary(a => a.AnswerText)}
}

Я просто думаю, что это упрощаетотображение.

...