2014-09-10 63 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某處。它開始真正讓我神經緊張。

相關問題