我有一个名为Option的域对象.它是更大的测验架构的一部分.该表中的前两个主键(Id)与Text列的值"true"和"false"相关联.但在那之后,该表中的项目对于该问题的范围没有任何影响.这两行"真"和"假"的重要性在于它们将被重复使用多次.
另请注意,Option表是一个标识(自动增量)表.我在OptionMap文件中有以下内容:
this.HasKey(t => t.Id);
this.Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Run Code Online (Sandbox Code Playgroud)
显然,每次在测验中添加带有true和false选项的新问题时,我不想继续向该表添加true和false.
在JavaScript中,在客户端,我编写了这样的代码,以便在创建新测验时,添加true和/或false作为问题的选项,然后将Id 1和2添加到发送到服务器的对象中(分别为真和假 - 召回前2行,如帖子顶部所述).当问题没有使用其中任何一个作为选项时,发送到服务器的选项的Id是未定义的.
在服务器上,在我的服务中,我编写了以下代码,它能够检测到作为选项添加了true或false,并尝试使用选项表中的现有存储值true/false(如果适用) :
foreach (var question in newQuestions)
{
_quizRepository.AddQuestion(question);
var options = question.QuestionWithOptions.Select(q => q.Option).ToList();
// This loop is an edge case. true and false will be very common answers. Rather than storing them over and over again,
// this loop will re-use the already stored answers for true and false, which complies with the quiz schema.
foreach (var option in options)
{
if (option.Text.Equals("true", StringComparison.OrdinalIgnoreCase) ||
option.Text.Equals("false", StringComparison.OrdinalIgnoreCase))
{
var storedOption = _quizRepository.Context.Option.Single(o => o.Id == option.Id);
foreach (var questionWithOption in question.QuestionWithOptions)
{
if (questionWithOption.Option.Id == storedOption.Id)
{
questionWithOption.Option = storedOption;
_quizRepository.Context.Entry(questionWithOption.Option).State = EntityState.Unchanged;
}
}
}
}
_quizRepository.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)
我试图将状态设置为Unchanged和Modified,但每次调用SaveChanges时,它都会为true和false添加新行.如上所述,这正是我想要避免的.
任何有关如何使用现有的"真实"和"假"选项保存这些新问题的帮助将不胜感激.
编辑 - 添加域类
题:
public partial class Question
{
public Question()
{
QuestionWithOptions = new List<QuestionWithOption>();
QuizWithQuestions = new List<QuizWithQuestion>();
}
public int Id { get; set; }
public string Text { get; set; }
public int? idTimeLimit { get; set; }
public QuestionType idType { get; set; }
public virtual ICollection<QuestionWithOption> QuestionWithOptions { get; set; }
public virtual ICollection<QuizWithQuestion> QuizWithQuestions { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
QuestionWithOption:
public partial class QuestionWithOption
{
public int Id { get; set; }
public int idQuestion { get; set; }
public int idOption { get; set; }
public bool CorrectAnswer { get; set; }
public string Letter { get; set; }
public virtual Option Option { get; set; }
public virtual Question Question { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
选项:
public partial class Option
{
public Option()
{
this.QuestionWithOptions = new List<QuestionWithOption>();
}
public int Id { get; set; }
public string Text { get; set; }
public virtual ICollection<QuestionWithOption> QuestionWithOptions { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
添加问题方法
这在以下两行代码之间切换(我正在尝试任何事情和所有事情)
public void AddQuestion(Question question)
{
//((TTSWebinarsContext) db).Question.Attach(question);
((TTSWebinarsContext) db).Question.Add(question);
}
Run Code Online (Sandbox Code Playgroud)
编辑 - 最终评论
让我加上这种情况多么荒谬.在同一操作中,它向Option表添加新选项(而不是使用现有选项1和2),插入QuestionWithOption表的值是正确的值,即1和2.因此,操作本身不是甚至声音.Option表中添加了多余的值,这些值甚至不是操作中的任何内容的FK.我开始了解NHibernate的粉丝了.
终于弄清楚了缺少的一件事。工作代码如下:
foreach (var question in newQuestions)
{
_quizRepository.AddQuestion(question);
var options = question.QuestionWithOptions.Select(q => q.Option).ToList();
// This loop is an edge case. true and false will be very common answers. Rather than storing them over and over again,
// this loop will re-use the already stored answers for true and false, which complies with the quiz schema.
var optionsToDelete = new List<Option>();
foreach (var option in options)
{
if (option.Text.Equals("true", StringComparison.OrdinalIgnoreCase) ||
option.Text.Equals("false", StringComparison.OrdinalIgnoreCase))
{
var storedOption = _quizRepository.Context.Option.Single(o => o.Id == option.Id);
foreach (var questionWithOption in question.QuestionWithOptions)
{
if (questionWithOption.Option.Id == storedOption.Id)
{
optionsToDelete.Add(option);
questionWithOption.idOption = storedOption.Id;
}
}
}
}
_quizRepository.Context.Option.RemoveRange(optionsToDelete);
_quizRepository.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)
当我按预期分配 StoredOption 时,最初添加到对象图中的选项是悬空的。所以我必须在调用 SaveChanges 之前将其从上下文中删除。我创建了一个列表来在 foreach 循环期间收集这些选项,然后在调用 SaveChanges 上方的行上调用 RemoveRange。
又脏又乱,但是有用。现有选项现在用于“true”和“false”,而不是一遍又一遍地创建它们。
| 归档时间: |
|
| 查看次数: |
564 次 |
| 最近记录: |