2013-01-22 59 views
2

我正在玩RavenDb並正在構建某種測驗。有不同類型的問題: - (A,B,C或d) 選擇題 - 日期(在何日會...?) - 數字(有多少......?)同一屬性中的不同對象類型

什麼我做的是創建一個基類問題,用屬性Question,其中包含問題作爲字符串和答案的列表,用戶已經給出。

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

然後我創建的多個亞類,它從Question繼承。 例如,NumberQuestion包含屬性MinimumValueMaximumValue,因爲每個問題存在差異。

我希望用戶給出答案,並將答案保存到數據庫中。問題是,答案可以是不同的類型,如DateTime,float或integer(多項選擇)。 我的問題是,在RavenDb中保存答案的最佳方法是什麼?

這是目前我在做什麼:

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

我在這裏做的,就是答案保存爲一個字符串,保存的文件類型(日期時間,漂浮等)也是,所以我可以在以後對其進行解析。

它可以工作,但我不太喜歡它。必須有另一種更好的方式。

+1

你爲什麼不'「非常喜歡」'..? – MethodMan

+0

我認爲必須有一個更清潔的解決方案。現在我必須解析每個答案,以檢查它是否正確,而不是直接比較它 – user1797792

回答

4

用戶之間的連接屬性,那麼只需將該屬性聲明爲公共基類型。在你的情況下,object將會很好。當序列化時,您將在json中獲得額外的$type字段,這將允許將它們反序列化爲適當的形式。

讓我們來看看我能否提供一些關於您的特定領域模型的建議。

  • 不要混淆可能的答案和實際的答案。給這些不同的名字讓它們保持直線。我將使用Choice來表示一個問題的可能答案,並用Answer來表示用戶給出的實際答案。

  • 請注意彙總實體的位置。這些都是以RavenDB作爲實際文檔並獲得Id的結果。在你的情況下,我只看到兩個 - QuestionExam

試試這個關於大小:

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; } 
} 
+0

感謝您的難以置信的答案! 我正在使用第一個建議,以'object'作爲屬性類型。但是,檢索答案時它是一個DateTime,它不會將其識別爲一個。雖然CreatedOn屬性始終是DateTime,但它確實可以識別它。我在Raven Management Studio中查看了它,兩個屬性看起來完全一樣。 RavenDb如何不將答案識別爲DateTime。我嘗試投射,但沒有奏效。 – user1797792

+0

有趣......它看起來好像沒有使用'$ type'字段來完成這個任務。可能是因爲這些是原始類型。它確實應該認識到它是一個日期。我會把這個報告給RavenDB團隊。但是 - 你確定你想要它作爲一個日期嗎?我的意思是,如果你的問題的答案是一個日期,那麼整個一天的精確度會不會提高?你也可以將它作爲一個字符串以預設格式存儲(可能是YYYY-MM-DD)。 –

+0

http://issues.hibernatingrhinos.com/issue/RavenDB-853 –

0

您可以使用泛型。創建通用類QuestionTAnswer其中TAnswer必須從抽象類Answer繼承。具體問題班會從該類繼承:

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 { 
    //... 
} 
+0

@ user1797792我希望我沒有誤解這個問題...... – Spontifixus

相關問題