我一直在玩RavenDB。我不得不说我印象非常深刻,但我很难理解如何更新子对象。例如,假设我们有以下内容:
public class Course
{
public int Id { get; set; }
public string Title { get; set; }
}
public class Student
{
public Student()
{
Courses = new Collection<Course>();
}
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Course> Courses { get; set; }
}
我可以在数据库中保存一个学生和两个与学生相关的课程。我可以在没有问题的情况下为学生加载两门课程。但是当我尝试修改课程时,例如student.Courses.Add(新课程{Id = 5,Title =“Accounting 101”}),我希望它能在数据库中的内容与当前的内容之间进行同步。 student.Courses。基本上,我希望它删除数据库中的课程,并且只在student.Courses中开设课程。这可能是我对RavenDB如何工作的误解。我找不到这样的例子。处理这种情况的最佳做法是什么?
答案 0 :(得分:1)
不,它不会做你所描述的任何内容。您对其进行建模的方式是,数据库中有两个单独的文档:
Course
{
Id : "courses/1",
Title : "Algebra"
}
Student
{
Id : "students/1",
Name : "John",
Courses :
[
{
Id : "courses/1",
Title : "Algebra"
}
]
}
将Course
非正规化为Student
的好处是,在查看Course
信息以获取课程标题时,您无需加载Student
个文档。
缺点是必须对两个文档进行Course
的任何更改。如果您只是向学生文档添加课程,则它指的是不存在的Course
文档。 Raven不会阻止你这样做。文档数据库中没有参照完整性约束。
在现实世界中,您可能会在将课程添加到学生之前添加课程,并且从课程中删除所有学生并不意味着没有课程。实际上,只有重命名课程才能触及课程文档和所有有关系的学生文档。
通常您只想使用IList<string> CourseIds
。没有要求你反规范化。有关详细信息,请查看this documentation。