2014-09-10 36 views
0

我有一个课程表:流利NHibernate的许多一对多映射保存所有的项目,但并没有得到所有项目

CourseID Name 
-------------------- 
1   Course 1 
2   Course 2 
3   Course 3 

交了白卷表:

QuizID CourseID Name 
---------------------------- 
1   1   Quiz 1 
2   1   Quiz 2 
3   1   Quiz 3 

一个问题表:

QuestionID Text 
----------------------------- 
1    What is foo? 
2    What is bar? 
3    What is foobar? 

并有QuizQuestion表:

QuizID QuestionID 
-------------------- 
1   1 
1   2 
2   2 
2   3 

前端来管理这些数据看起来像这样(我希望我在它怎么看都更说):

enter image description here

的UI可能并不重要,但希望它给你一个更好的主意。我使用的流利NHibernate与以下映射:

public class CourseMapOverride : IAutoMappingOverride<Course> 
{ 
    public void Override(AutoMapping<Course> mapping) 
    { 
     mapping.Table("Course"); 

     mapping.Id(x => x.Id).Column("CourseID"); 

     mapping.HasMany(x => x.Exams) 
       .KeyColumn("CourseID") 
       .Cascade.All() 
       .Inverse(); 
    } 
} 

public class ExamMapOverride : IAutoMappingOverride<Exam> 
{ 
    public void Override(AutoMapping<Exam> mapping) 
    { 
     mapping.Table("Quiz"); 

     mapping.Id(x => x.Id).Column("QuizID"); 

     mapping.References(x => x.Course).Column("CourseID"); 

     mapping.HasManyToMany(x => x.Questions) 
       .Table("QuizQuestion") 
       .ParentKeyColumn("QuizID") 
       .ChildKeyColumn("QuestionID") 
       .Cascade.All(); 
    } 
} 

public class QuestionMapOverride : IAutoMappingOverride<Question> 
{ 
    public void Override(AutoMapping<Question> mapping) 
    { 
     mapping.Table("Question"); 

     mapping.Id(x => x.Id).Column("QuestionID"); 

     mapping.HasManyToMany(x => x.Exams) 
       .Table("QuizQuestion") 
       .ParentKeyColumn("QuestionID") 
       .ChildKeyColumn("QuizID") 
       .Cascade.All() 
       .Inverse(); 
    } 
} 

是的,测试表映射到考试类出于某种原因。当表单发布后,我查看每个复选框,确定QuizQuestion是否已经存在,如果不存在,则插入新行。这部分工作正常,但这里是反正代码:

public void UpdateCourse(EditCourseModel model) 
{ 
    var course = CourseRepository.Get(model.CourseID); 

    course.Name = model.Name; 

    foreach (var examQuestionModel in model.Questions 
              .SelectMany(q => q.ExamQuestions) 
              .Where(eq => eq.Selected)) 
    { 
     UpdateExamQuestion(course, examQuestionModel); 
    } 
} 

private void UpdateExamQuestion(Course course, ExamQuestionModel model) 
{ 
    var exam = course.Exams.First(e => e.Id == model.ExamID); 

    if (exam.Questions.Any(q => q.Id == model.QuestionID)) 
    { 
     // it already exists 
     return; 
    } 

    var question = QuestionRepository.Get(model.QuestionID); 

    exam.Questions.Add(question); 

    question.Exams.Add(exam); 
} 

说,例如,我选择下面的复选框:

enter image description here

后,我张贴的形式,我可以验证新行是通过在数据库中查找在QuizQuestion表补充说:

QuizID QuestionID 
-------------------- 
1   1 
1   2 
2   2 
2   3 
3   1 
3   3 

出于某种原因,但是,新的行不是数据S的一部分et显示在下一页上。之后保存/提交/平/重定向,接下来的页面看起来完全就像它之前:这是

enter image description here

不认为有问题,因为当我暂停在foreach循环的内部调试器GetQuestionModel方法(如下),exam.Questions是空的:

public CourseModel GetCourseModel(int courseID) 
{ 
    var course = CourseRepository.Get(courseID); 

    var questions = QuestionRepository.GetAll() 
             .Select(q => GetQuestionModel(course.Exams, q)) 
             .ToList(); 

    return new CourseModel 
       { 
        CourseID = course.ID, 
        Name = course.Name, 
        Questions = questions, 
       }; 
} 

public QuestionModel GetQuestionModel(IEnumerable<Exam> exams, Question question) 
{ 
    var model = new QuestionModel 
        { 
         QuestionID = question.ID, 
         Text = question.Text, 
         ExamQuestions = new List<ExamQuestionModel>(), 
        }; 

    foreach (var exam in exams) 
    { 
     // exam.Questions is empty when exam.ID is 3 
     var examQuestionIDs = exam.Questions.Select(q => q.ID); 

     model.ExamQuestions.Add(new ExamQuestionModel 
            { 
             ExamID = exam.ID, 
             QuestionID = question.ID, 
             Selected = examQuestionIDs.Contains(question.ID), 
            }); 
    } 

    return model; 
} 

下面是来自存储库类GETALL方法:

public virtual IQueryable<T> GetAll() 
{ 
    return LinqExtensionMethods.Query<T>(this.Session); 
} 

这整个事情中最奇怪的部分是如果我重建解决方案的问题修复自己。它必须是重建,或者是代码更改,然后是构建。

这让我焦躁不安。我究竟做错了什么?

编辑

我怀疑这有事可做与NHibernate缓存,所以我申请this mapping convention。然而,没有运气。

EDIT 2

正如我刚才所说,重建莫名其妙地刷新数据。我能够为ID为3的测验增加几个问题,重建后他们出现在列表中。然后我删除了连接表中的所有行,但问题仍然是列表中的。现在我更加确信这可能是NHibernate缓存的问题。

回答

0

我终于发现了问题:

var questions = QuestionRepository.GetAll() 
            .Select(q => GetQuestionModel(course.Exams, q)) 
            .ToList(); 

应该是:

var questions = QuestionRepository.GetAll() 
            .ToList() 
            .Select(q => GetQuestionModel(course.Exams, q)) 
            .ToList(); 

似乎每次我有一个令人沮丧的难题与NHibernate的时间,那是因为我缺少一个电话ToList某处。它开始真正让我神经紧张。

相关问题