我对“实体集”和“关系集”感到困惑。我知道“实体”和“关系”。对于实体集和关系集,是否有任何清晰的示例可以显示这些术语的实际用例?
___________ /\ ___________
| | / \ | |
| Teacher |-------- /Tea \--------| Student |
|___________| \che / |___________|
\s /
\/
在上图中,教师和学生是实体,教学是一种关系。
最初在实体关系建模中:实体是一件事。某些事物之间的关系或某些事物之间的关联是单个(具体的或概念的)事物。两者都可以具有属性。实体或关系/关联类型/集合/类别是实体或关系/关联的集合。类型/集合/类对应于一个关系,并且每个实体或关系/关联都包含一行作为元素/成员的行。实体或关系/关联称为它是元素/成员的类型/集合/类的实例。
但是,“实体”被用作“实体类”的简写,而“关联”被用作“关联类”。当然,这令人困惑。然后,将“实体实例”用于“实体”,将“类实例”用于“类”。更令人困惑。这意味着我们可以看到实体或关系“集合/类实例”,它表示实体或关系。啊。但是实体或关联的“类型”用来表示具有实体和关系/关联的集合/类的所谓potential事物的集合/集合,意味着这些类型的潜在元素/成员实际上确实对应于当前情况/状态的事物。 (就像关系的行“类型”一样,它表示所有可能存在的元组的集合,而关系是一组实际存在的元组的集合。或者像类与范围一样。)Ughnnnn。您只需要弄清楚作者如何使用术语。
[许多有关E-RM或变体的介绍或产品也错误地使用“关系”来表示“外键”。
[Boo是一名教师,是且仅当Boo是一名教师时,才是实体(实例)的示例。当且仅当吉是学生时,吉是学生才是实体(实例)的示例。当且仅当Boo教Gee时,Boo教Gee是一个关系/关联(实例)。教师是一个实体类型/集合/类,包含所有此类实体(实例)。学生是一个实体类型/集合/类,包含所有此类实体(实例)。教导是一种关系/关联类型/集合/类别,包含所有此类关联/关联(实例)。矩形表示实体类型/集合/类别。菱形表示关系/关联类型/集合/类别。矩形和菱形对应关系(具有参与者事物的属性以及拥有/拥有/关联的财产事物)。从菱形到矩形的线表示实体类型/集合/类别在关系/关联类型/集合/类别的关系/关联中的参与(以及从关系/关联关系到参与者实体关系的外键)。
具有讽刺意味的是,术语的所有这些变体和混淆都是指首先不需要的概念。 E-RM在“实体”事物,“关系/关联”事物和“财产”事物之间,以及作为事物的财产和与之建立关系/联系之间,进行不必要的区分。直接进行关系建模可以避免所有这些情况。 每个查询的每个超键与某种种类/类型的事物是1:1对应的。但是E-R建模和变体只是不了解关系模型。
请参见A: What is the difference between an entity relationship model and a relational model?。
实体集通常是可见的(通过DbSet<T>
,ICollection<T>
公开),而使用Linq to Entity时,关系集看起来像hidden。您可以访问集合的导航属性,查询某些实体,关于实体集非常明显。
对于关系集,它不是那么明显。实际上,所谓的navigation property
代表关系。关系包含有关两端的信息,因此看起来像一个链接。实体看起来像2个端点之一。
例如:,您有2位老师T1,T2和2位学生S1,S2。这取决于关系的类型,可以有不同的关系集。
对于一对一关系,假设T1教S1,T2教S2。因此,关系集仅包含2个条目:(T1-S1),(T2-S2)。通过在两个表之一中定义的外键列可以维护此关系:Teacher
或Student
。在代码中,可以通过仅更改导航属性(参考)来修改/建立关系:
T1.Student = S1;
T2.Student = S2;
//or
S1.Teacher = T1;
S2.Teacher = T2;
对于一对多关系,假设T1教S1,S2和T2是保留的(不教学生)。我们还有2种关系:(T1-S1),(T1-S2)。这种关系是通过在多面表中定义的外键列(在本例中为Student
)维护的。然后,Teacher
公开Students
的集合,而Student
仅公开对Teacher
的引用。在代码中,您可以通过更改以下导航属性之一来修改/建立关系:
//via Teacher navigation property
S1.Teacher = T1;
S2.Teacher = T1;
//or via Students navigation property
//NOTE: this is for demonstration, in practice doing something
//like this should be done carefully.
//Students should be fully loaded first, otherwise
//if lazy loading is enabled, the new list will be merged with
//loaded data before being set to Students.
//This may null out some foreign keys (if foreign key column is nullable)
//Otherwise an exception will be thrown after calling SaveChanges()
T1.Students = new List<Student>{ S1, S2 };
对于多对多关系,假设两个老师都教两个学生,现在我们有4个关系:(T1-S1),(T1-S2),(T2-S1)和(T2-S2)。通过包含两个外键(指向Teacher
和Student
表)的联结(联接)表可以维护这种关系。然后,Teacher
公开Students
的集合,Student
公开Teachers
的集合。在代码中,您可以通过更改以下导航属性之一来修改/建立关系:
//Setting collection navigation property
//like this has the same note as above (about merging collection)
//However there won't be no exception
//It's easier than one-many relationship.
S1.Teachers = new List<Teacher> { T1, T2};
S2.Teachers = new List<Teacher> { T1, T2};
//or
T1.Students = new List<Student> { S1, S2};
T2.Students = new List<Student> { S1, S2};
上面的代码主要用于演示目的(尽管在某些特定场景/上下文中可以工作)。实际上,您可以使用Remove
,Clear
,Add
方法修改集合导航属性。列表值也可以从数据库中查询(而不是创建一个新值)。最明显的是,在修改one-many关系的集合导航属性时。相对于这种关系,修改/更改参考导航属性更为安全。