【发布时间】:2015-09-13 07:00:04
【问题描述】:
我有一个名为 Option 的域对象。它是更大的测验模式的一部分。该表中的前两个主键 (Id) 与 Text 列的值“true”和“false”相关。但在那之后,该表中的项目对这个问题的范围没有影响。 “真”和“假”这两行的意义在于它们会被重复使用很多次。
另请注意,选项表是一个标识(自动增量)表。我的 OptionMap 文件中确实有以下内容:
this.HasKey(t => t.Id);
this.Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
显然,我不想每次在测验中添加一个以真假为选项的新问题时,都在该表中添加真假。
在客户端的 JavaScript 中,我对其进行了编码,以便在创建新测验并添加 true 和/或 false 作为问题的选项时,将 Id 1 和 2 添加到发送的对象中到服务器(分别为 true 和 false - 回忆前 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();
}
我尝试将状态设置为未更改和已修改,但每次调用 SaveChanges 时,它都会为真假添加新行。如上所述,这正是我想要避免的。
任何帮助我弄清楚如何使用现有的“真”和“假”选项保存这些新问题将不胜感激。
编辑 - 添加域类
问题:
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; }
}
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; }
}
选项:
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; }
}
添加问题方法
这会在以下两行代码之间切换(我正在尝试任何事情)
public void AddQuestion(Question question)
{
//((TTSWebinarsContext) db).Question.Attach(question);
((TTSWebinarsContext) db).Question.Add(question);
}
编辑 - 最终评论
让我补充一下这种情况有多荒谬。在同一个操作中,向选项表添加新选项(而不是使用现有的选项 1 和 2),插入 QuestionWithOption 表的值是正确的值,即 1 和 2。因此,操作本身不是甚至声音。选项表中添加了一些冗余值,这些值甚至不是操作中任何内容的 FK。我开始了解 NHibernate 的粉丝。
【问题讨论】:
-
可以为 Question、QuestionWithOption 和 Option 添加代码吗?
-
AddQuestion 的代码也可以提供帮助。
-
AddQuestion 中的 db 是从哪里来的?我尝试实现您的代码并且一切正常,但我确保我在同一上下文中进行了所有更改。每个上下文都会跟踪它自己的变化,所以也许这就是问题所在。
-
@MrSangrief AddQuestion 在存储库中,它使用相同的上下文。当你说它有效时,你确定它没有为真假添加新行吗?
-
我已将我的代码添加为 anwser。您当时没有发布您的源代码,所以我尝试自己重新创建您的设置。
标签: entity-framework