LINQ 选择“新建”以从超类型子类型关系创建一个表
本文关键字:类型 创建 一个 关系 新建 LINQ 超类 选择 | 更新日期: 2023-09-27 18:30:43
我正在使用一个SQL数据库(对它来说还很新),并尝试创建"一对一"或子表超级表关系。我正在使用 C# 和 LINQ to-Entities。
作为一个常见的例子,我有 3 张桌子。
Person:
PersonId, Age, p1, p2, ..., pn
Student:
PersonId, Grade, GPA, s1, s2, ...., sn
Teacher:
PersonId, PrimarySubject, YearsAtSchool, IsCoach, ....
我希望能够做的是基于 Person 进行查询,然后获取相关的子类型数据。我有相关的TypeId表来确保关系。
假设我询问了一个人,而他们是学生,那么我想得到:
QueriedResult
PersonId, Age, p1, ..., pn, Grade, GPA, s1, ..., Sn
不幸的是,选择新的{p.PersonID等}是不可行的,因为在我的情况下有太多的子表和太多的元素。
每当我使用我的代码时,我都会得到两个单独表的 IEnumerable。我提供的示例代码在没有关联的学生时返回 null,如果此人是学生,则在第二列中返回一个表。
var query = (from p in Persons.AsEnumerable()
join s in Students on p.PersonId equals s.PersonId
select new {p, s});
我听过很多关于"扁平化"的讨论,尽管所有建议的方法似乎都要求p&s属于相同的表类型。
谢谢
您正在努力建模继承。 Student
和Teacher
都是Person
。有几种方法可以在关系数据库中存储继承的类,实体框架支持这些方法。
可能最有帮助的方法称为每个具体类型的表 (TPC),这意味着每种类型在数据库中都有自己的表,而 EF 负责将子类型存储在正确的表中。该链接还引用了另外两种通信方法(TPH 和 TPT)。TPT 也可能是合适的,如果你的子类有相对多的共同点。
所以你会有
abstract class Person { PersonId, ... }
class Student : Person { Grade, ... }
class Teacher: Person { PrimarySubject, ... }
如果你想要Student
你做
context.Persons.OfType<Student>().Where(....
这为您提供了预期的QueriedResult
结果。
请注意,Person
是抽象的。如果你想让它具体化,你最好做一个抽象的PersonBase
类(或类似的东西)并从中派生Person
,就像Student
和Teacher
一样。