繁体   English   中英

LINQ Select 新建超类型子类型关系建一张表

[英]LINQ Select New to create one table from super-type sub-type relationship

我正在使用 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 的查询,然后也得到相关的子类型数据。 我有 relevatn TypeId 表来确保关系。

假设我查询一个人并且他们是学生,那么我想得到:

QueriedResult
PersonId, Age, p1, ..., pn, Grade, GPA, s1, ..., Sn 

不幸的是,做 select new {p.PersonID, etc} 是不可行的,因为在我的例子中有太多的子表和太多的元素。

每当我使用我的代码时,我都会得到一个包含两个单独表的 IEnumerable。 当没有关联学生时,我提供的示例代码会返回空值,如果此人是学生,则会在第二列中返回一个表。

var query = (from p in Persons.AsEnumerable()
join s in Students on p.PersonId equals s.PersonId
select new {p, s});

我听过很多关于“扁平化”的讨论,尽管所有建议的方法似乎都要求 p & s 具有相同的表类型。

谢谢,

您正在努力建模 inheritance。 StudentTeacher都是Person 有几种方法可以将继承的类存储在关系数据库中,实体框架支持这些方法。

可能对您最有帮助的方法称为Table per Concrete Type (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 class(或类似的)并从中派生Person ,就像StudentTeacher一样。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM