Добрый день.
Разрабатываю систему онлайн-тестов на ASP MVC 5, в связи с чем возник по организации базы данных (EF6).
В системе есть тест, в котором есть вопросы. Вопросы можно редактировать, удалять из теста и т.п.
Ситуация 1: тест выдан в состоянии А студентам, после чего был отредактирован в состояние Б. В результате ссылки в результатах теста, ведущие на А становятся неактуальными.
Ситуация 2: из пройденного теста удаляем вопрос. Удалить из базы мы его не можем, т.к. тогда результаты будут неверными, но и не удалить из списка вопросов также не можем, т.к. тогда теряется связь с тестом.
В качестве решения я предполагаю сделать привязку всех сущностей ко времени (т.е. ссылка в результатах теста будет на вопрос с Id=XXX и временем изменения=YYY). Но как быть с удалением - я не понимаю.
Посоветуйте, что тут можно сделать.
public class ExerciseSet
{
[Key]
public string Id { get; set; } = Guid.NewGuid().ToString();
[Display(Name = "Название")]
public string Name { get; set; }
public string Owner { get; set; }
public virtual List<ExerciseBlock> ExercisesBlocks { get; set; } = new List<ExerciseBlock>();
public virtual List<GeneratedVariant> GeneratedVariants { get; set; } = new List<GeneratedVariant>();
[Display(Name = "Примечания")]
public string Notes { get; set; }
public ExerciseSet()
{
}
public ExerciseSet(string ownerId)
{
Owner = ownerId;
}
[NotMapped]
[Display(Name = "Кол-во заданий")]
public int ExercisesCount => ExercisesBlocks.SelectMany(x => x.Exercises).Count();
}
public class ExerciseBlock
{
[Key]
public int Id { get; set; }
[Display(Name = "Название")]
public string Name { get; set; }
public virtual ExerciseSet ExerciseSet {get; set; }
public virtual List<Exercise> Exercises { get; set; }
}
public class Exercise
{
[Key]
[HiddenInput(DisplayValue = false)]
public string Id { get; set; }
public virtual ExerciseBlock ExerciseBlock { get; set; }
/// <summary>
/// Список блоков вопроса, блоки выводятся в соотв. с порядком
/// </summary>
[Display(Name = "Блоки вопроса")]
public virtual IList<Resource> AskBlocks { get; set; }
/// <summary>
/// Ответ на вопрос
/// </summary>
[Display(Name = "Варианты ответа")]
public virtual IList<ExerciseAnswer> Answers { get; set; }
public string AnswerType { get; set; }
/// <summary>
/// Подсказка для режима Обучения
/// </summary>
[Display(Name = "Подсказка (Обучение)")]
public string Hint { get;set; }
/// <summary>
/// Id тестируемого предмета
/// </summary>
[Display(Name = "Предмет")]
public string Subject { get; set; }
/// <summary>
/// Id тестируемой темы
/// </summary>
[Display(Name = "Тема")]
public string Topic { get; set; } = "";
/// <summary>
/// Id тестируемого класса
/// </summary>
[Display(Name = "Класс")]
public string Class { get; set; } = "";
/// <summary>
/// Id используемого кодификатора
/// </summary>
[Display(Name = "Кодификатор")]
public virtual Codificator Codificator { get; set; }
public int? CodificatorId { get; set; }
/// <summary>
/// Номер проверяемого элемента по кодификатору
/// </summary>
[Display(Name = "Элемент кодификатора")]
public virtual CodificatorSection CodificatorElement { get; set; }
public int? CodificatorElementId { get; set; }
/// <summary>
/// Номер требования к подготовке по кодификатору.
/// </summary>
[Display(Name = "Требование кодификатора")]
public virtual CodificatorSection CodificatorRequirement { get; set; }
public int? CodificatorRequirementId { get; set; }
///// <summary>
///// Сложность (базовая, повышенная, высокая)
///// </summary>
//[Display(Name = "Сложность")]
//public ExerciseBlock Difficulty { get; set; }
/// <summary>
/// Время выполнения задания
/// </summary>
[Display(Name = "Время на выполнение задания")]
public TimeSpan Time { get; set; }
/// <summary>
/// Кол-во баллов за выполнение задания
/// </summary>
[Display(Name = "Количество баллов")]
public int Points { get; set; }
/// <summary>
/// Заметка к заданию
/// </summary>
[Display(Name = "Примечания")]
public string Notes { get; set; }
public Exercise()
{
Id = Guid.NewGuid().ToString();
AskBlocks = new List<Resource>();
Answers = new List<ExerciseAnswer>();
}
}