3

私はRavenDbで遊んでいて、ある種のクイズを作成しています。質問にはさまざまな種類があります。-複数選択(A、B、C、またはD?)-日付(何日に...?)-数(いくつ...?)

私が行ったのはQuestion、ユーザーが指定した文字列としての質問と回答のリストを含むプロパティを使用して、基本クラスの質問を作成することです。

public class Question
{
    public string Question { get; set; }
    public List<Answer> Answers { get; set; }
}

次に、から継承する複数のサブクラスを作成しましたQuestion。たとえば、質問ごとにこの違いがあるため、NumberQuestionにはプロパティMinimumValueとが含まれます。MaximumValue

ユーザーに答えてもらい、その答えをデータベースに保存してほしい。問題は、答えがDateTime、float、integer(複数選択)などのさまざまなタイプである可能性があることです。私の質問は、回答をRavenDbに保存するための最良の方法は何ですか?

これは私が現在行っていることです:

public class Answer
{
    public User User { get; set; }
    public string AnswerString { get; set; }
    public string AnswerType { get; set; }
}

ここで行うのは、回答を文字列として保存し、タイプ(DateTime、floatなど)も保存することです。これにより、後で解析できるようになります。

動作しますが、あまり好きではありません。別のより良い方法があるはずです。

4

2 に答える 2

4

同じプロパティに複数の型を格納する場合は、そのプロパティを共通の基本型として宣言するだけです。あなたの場合objectはうまくいきます。シリアル化すると、json に追加$typeのフィールドが取得され、適切な形式に逆シリアル化できるようになります。

あなたの特定のドメイン モデルについてアドバイスできるかどうか見てみましょう。

  • 考えられる答えと実際の答えを混同しないでください。それらを明確にするために、これらの異なる名前を付けてください。Choice質問に対する可能な回答をAnswer表し、ユーザーからの実際の回答を表すために使用します。

  • 集約エンティティがどこにあるかに注意してください。これらは実際のドキュメントとして RavenDB に格納され、ID を取得します。あなたの場合、私は 2 つの -Questionとしか表示しませんExam

これを試着してサイズを確認してください:

public abstract class Question
{
    public string Id { get; set; }
    public string QuestionText { get; set; }
}

public class ValueQuestion : Question
{
    public object CorrectValue { get; set; }
}

public class RangeQuestion : Question
{
    public object MinCorrectValue { get; set; }
    public object MaxCorrectValue { get; set; }
}

public class MultipleChoiceQuestion : Question
{
    public int NumberOfChoicesAllowed { get; set; }
    public List<MultipleChoiceOption> Choices { get; set; }
}

public class MultipleChoiceOption
{
    public char Letter { get; set; }
    public bool Correct { get; set; }
    public object Value { get; set; }
}

public class EssayQuestion : Question
{
    public int MinAnswerLength { get; set; }
    public int MaxAnswerLength { get; set; }
}

public class Exam
{
    public string Id { get; set; }
    public string UserId { get; set; }
    public DateTime Taken { get; set; }
    public decimal Score { get; set; }
    public List<Answer> Answers { get; set; }
}

public class Answer
{
    public string QuestionId { get; set; }
    public bool Correct { get; set; }
    public object Value { get; set; }
}

ジェネリックは魅力的かもしれませんが、あまり買わないことがわかると思います. 最終的に、ドキュメントの構造は同じになり、データベースのレイアウトも同じになります。おそらく唯一の違いは、$typeフィールドが異なる場所で使用されていることです。

ジェネリック ベースのソリューションを試してみたい場合は、次の方法を試してください。

public abstract class Question
{
    public string Id { get; set; }
    public string QuestionText { get; set; }
}

public class ValueQuestion<T> : Question
{
    public T CorrectValue { get; set; }
}

public class RangeQuestion<T> : Question
{
    public T MinCorrectValue { get; set; }
    public T MaxCorrectValue { get; set; }
}

public class MultipleChoiceQuestion<T> : Question
{
    public int NumberOfChoicesAllowed { get; set; }
    public List<MultipleChoiceOption<T>> Choices { get; set; }
}

public class MultipleChoiceOption<T>
{
    public char Letter { get; set; }
    public bool Correct { get; set; }
    public T Value { get; set; }
}

public class EssayQuestion : Question
{
    public int MinAnswerLength { get; set; }
    public int MaxAnswerLength { get; set; }
}

public class Exam
{
    public string Id { get; set; }
    public string UserId { get; set; }
    public DateTime Taken { get; set; }
    public decimal Score { get; set; }
    public List<IAnswer> Answers { get; set; }
}

public interface IAnswer
{
    string QuestionId { get; set; }
    bool Correct { get; set; }
}

public class Answer<T> : IAnswer
{
    public string QuestionId { get; set; }
    public bool Correct { get; set; }
    public T Value { get; set; }
}
于 2013-01-22T15:38:10.707 に答える
0

ジェネリックを使用できます。抽象クラスから継承する必要がある場所のジェネリック クラスQuestionを作成します。特定の質問クラスは、そのクラスから継承されます。TAnswerTAnswerAnswer

public abstract class Question<TAnswer> where TAnswer : Answer
{
    public Guid Id { get; set; }
    public string Question { get; set; }
    public List<TAnswer> Answers { get; set; }
}

public class DateQuestion : Question<DateAnswer>
{
    //...
}

回答に使用するクラスはすべて基本クラスから継承されます。この基本クラスAnswerには、質問が属する質問と回答したユーザーへの参照があります。次に、回答タイプごとに個別のテーブルを作成して、質問、回答、およびそれらに回答したユーザー間の接続を維持しながら、タイプの解析を防ぐことができます。

public abstract class Answer {
    public Guid QuestionId { get; set; }
    public Guid UserId { get; set; }
}

public class MultipleChoiceAnswer :Answer {
    //...
}

public class DateAnswer : Answer {
    //...
}
于 2013-01-22T09:56:09.307 に答える