2012-04-10 69 views
0

我正在使用SQL數據庫(對它仍然相當新),並且試圖創建「one-to-one」或子表超級關係。我正在使用C#和LINQ-to-Entities。LINQ選擇New以從超類型子類型關係中創建一個表

作爲一個常見的例子,我有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 

不幸的是,它不feasibe做選擇新{p.PersonID等}因爲有在我的情況下太多的子表和太多的元素。

每當我使用我的代碼,我得到一個IEnumerable的兩個獨立的表。我提供的示例代碼在沒有關聯的學生時返回空值,如果此人是學生,則返回第二列中的表格。

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

我聽說了很多談「扁平化」的,雖然所有建議的方法似乎要求採用p & s到相同的表型。

謝謝,

回答

0

你正在努力與modelliing繼承。 StudentTeacher都是Person s。有多種方法可以將關聯數據庫中的繼承類存儲,實體框架支持這些關聯數據庫。

可能最能幫助你的方法叫做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類(或類似),並從它派生Person,就像StudentTeacher

+0

這對我有意義。在我的情況下,人與其他表有很多關係,並有5個子類型。在TPC中,我將每個5個子表連接到Person的每個連接表?鏈接太棒了! – Sethery 2012-04-16 16:12:46

+0

是的,這就是你通常用的子類型。我必須說分類是很棒的,但很多人(包括我)贊成「構圖而非繼承」。如果你在谷歌上,你會被鏈接充斥。從GoF傢伙開始,着名的設計模式創始人。 – 2012-04-16 20:09:23