2013-01-22 5 views
2

나는 RavenDb에서 놀고 있으며 퀴즈를 만들고 있습니다. 질문의 다른 종류가 있습니다 : - (? A, B, C 또는 D) 여러 선택은 - 날짜 (어떤 일에했다 ...?) - 수 (얼마나 많은 ...?)동일한 속성의 다른 객체 유형

무엇을 나는 기본 클래스 질문을 만들었습니다.이 질문은 문자열과 Answers 목록으로 질문이 포함 된 Question 속성을 사용하여 사용자가 제공했습니다.

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

은 그 때 나는 Question에서 상속 여러 서브 클래스를 만들었습니다. 예를 들어 NumberQuestion에는 MinimumValueMaximumValue 속성이 포함되어 있습니다.

사용자가 답변을주고 데이터베이스에 저장하기를 원합니다. 문제는 응답이 DateTime, 부동 또는 정수 (객관식)와 같은 여러 유형이 될 수 있다는 것입니다. 내 질문은 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'를 속성 유형으로 사용하여 첫 번째 제안을 사용하고 있습니다. 그러나 Answer를 검색 할 때 DateTime 인 경우이를 인식하지 못합니다. CreatedOn 속성은 항상 DateTime이며이를 인식합니다. 저는 Raven Management Studio에서 이것을 살펴 보았고 두 속성은 완전히 똑같습니다. 어떻게 RavenDb가 답변을 DateTime으로 인식하지 못합니까? 나는 캐스팅을 시도했지만 작동하지 않았습니다. – user1797792

+0

흥미 롭습니다 ...이 afterall에'$ 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

관련 문제