Linq to SQL,多对多设计

joe*_*ish 1 c# sql linq-to-sql

我正在尝试获取一个对象并设计一个SQL表来存储它.该对象有一个名为"Roles"的成员,它是一个包含4个值的枚举.每个对象可以有几个不同的角色.

现在,我已经使用枚举并从中创建了一个同名的SQL表,并添加了4个角色.现在我正在尝试设计对象表,我无法弄清楚如何让多对多的关系为它工作.我也希望它与Linq-to-SQL一起使用.保留枚举会很好,但如果不是,字符串数组也可以工作.

简而言之,我需要一个在Roles和Object.Roles(或Object.Roles [])之间具有多对多的表.

谢谢!

Tom*_*han 9

通常,Linq2SQL(和实体框架)中的多对多关系是通过引入关联表来创建的,只有来自要链接的两个表的主键,以及每行对应一个关联.

由于您RoleObject.Role可能难以保持相隔试图解释这一点,我再举个例子:在一个学校,每个老师可以有很多的学生,并且每个学生可以有很多老师.然后表示这个的表结构

Teachers                    Students                     StudentTeacherRelations
********                    ********                     ***********************
TeacherId                   StudentId                    TeacherId
FirstName                   FirstName                    StudentId
etc...                      etc...
Run Code Online (Sandbox Code Playgroud)

现在,Linq2SQL和EF都足够聪明,可以将其识别为多对多关系,并在模型中引入导航属性.具有Student对象的适当属性的POCO可能如下所示:

public class Student
{
    public int StudentId { get; set; }
    public string FirstName { get; set; }
    // etc
    public IEnumerable<Teacher> Teachers { get; }
}
Run Code Online (Sandbox Code Playgroud)

如果设置正确,则O/R映射器将自动填充Teachers属性.

更新:在回应评论时,如果我想要包含一个场景,每个教师可以给一些学生做好由多个问题组成的作业,这里是我如何构建数据库的其余部分:

HomeworkAssignments          Questions                      Answers
*******************          *********                      *******
HomeworkAssignmentId (pk)    QuestionId (pk)                AnswerId (pk)
...                          HomeworkAssignmentId (fk)      QuestionId (fk)
                             ...                            StudentId (fk)
                                                            ...

StudentHomeworkAssignmentRelations    TeacherHomeworkAssignmentRelations
**********************************    **********************************
StudentId (fk)                        Teacherid (fk)
HomeworkAssignmentId (fk)             HomeworkAssignmentId (fk)
Run Code Online (Sandbox Code Playgroud)

如你所见,这里有很多表.但是,这种结构允许您让每位教师创建许多家庭作业,然后将每个作业交给许多学生.您将拥有Student.HomeworkAssignments类型的导航属性IEnumerable<HomeworkAssignment>,通过该属性您可以找到学生必须回答的所有问题.对于每个已发布的答案,您在Answers表格中存储一行,该行通过一对多关系链接到问题和学生 - 每个答案只能属于一个问题,并且仅由一个学生提供.

这里的关键是你不需要能够直接访问学生给出的每个答案 - 在Linq2SQL和EF中,可以通过各种方式同时从多个表中请求数据.其中一种方法是

var answersToTheLastExam = context.Students
                  .SelectMany(s => s.HomeworkAssignments)
                  .OrderBy(ha => ha.Date) // this might need modifying to get the last one first
                  .First(ha => ha.Questions.Count() > 0)
                  .SelectMany(ha => ha.Questions)
                  .SelectMany(q => q.Answers)
                  .Where(a => a.StudentId == myId)
Run Code Online (Sandbox Code Playgroud)

请注意,此代码未经测试,可能无法正常工作.我只是在这里尽我所能=)