2012-03-13 19 views
0

這裏是一個SQL Server/ADO.Net實體框架問題:我正在尋找「最好」的方式來做到這一點。SQL Server/ADO.Net:具有多部分FK主鍵的實體,其中一部分是可選的?

我具有類似於下面的對象的分層結構:

Company -> Division -> Department -> Group -> Specialty 

每個的主鍵(除其他公司)由一個外鍵指向每個祖先的PK的。所以,專業看起來是這樣的:

[PK/FK] CompanyID (string) 
[PK/FK] DivisionID (int) 
[PK/FK] DepartmentID (int) 
[PK/FK] GroupID (int) 
[PK] SpecialtyID (int) 
     Name (string) 
     Description (string) 

此基礎結構必須留在原地的原因,我不會去 - 所以使用GUID的PK真的不是在卡 - 我們要與依賴於該結構反映的「Bergdorf.6.3.4.1」ID構造的其他應用程序進行交互。

但是,我現在需要做的是添加添加適用於整個Department而不是組的專業的功能。所以,在一個理想的世界,我們就會有這樣的:

[PK/FK] CompanyID (string) 
[PK/FK] DivisionID (int) 
[PK/FK] DepartmentID (int) 
[PK/FK] GroupID (int/NULL) 
[PK] SpecialtyID (int) 
     Name (string) 
     Description (string) 

...等,如果專業的羣ID爲空,這意味着它適用於整個部門。

但是,當然,你不能有一個可爲空的字段作爲PK的一部分。所以這是一個不行。

它也不會將GroupID從PK中拉出來,因爲然後SpecialtyID將在整個Department中必須是唯一的,並且我們已經建立了使這不可能的ID。

由於FK約束要求我們爲每個Department創建一個ID爲-1的組,因此無法創建「特殊」GroupID(例如「-1」),意思是「無組」。

......那麼......在這裏做什麼是正確的事情?我是否必須爲專業製作GUID,並將所有FK從PK中抽出?如果可能的話,真的很想避免這種情況。

任何想法將不勝感激!

回答

0

您可以創建一個外部參照表連接類專業部門:xSpecialtyDepartment(SpecialtyID int, DepartmentID int)

+0

不知道我明白這將如何解決問題?請詳細說明......謝謝! – DanM 2012-03-14 02:53:04

+0

專業是Group的孩子,而Specialty.GroupID是空的,正確的?我是否正確理解該組是子部門的孩子? – 2012-03-14 03:30:48

+0

外部參照表背後的想法僅僅是爲了允許專業與部門之間的多對多關係。 – 2012-03-14 04:04:12

1

我建議你有兩個沒有空列(亞型)基表:一個用於系專業,另一個是集團專業。您可能需要爲所有專業設置第三個(超類型)表格,以便您可以擁有SpecialtyID值,這對所有專業人士來說都是唯一的,而不管子類型如何。

然後你coould有VIEWUNION S中的亞型在一起,在這裏你可以爲「丟失」 GroupID S代表系專業介紹默認值(例如-1)。你可以走得更遠,只會暴露VIEW,不要公開基表,並使用上的INSTEAD OF觸發器來更新基表。

您無論如何都需要一種機制來確保對於每個專業(超類型)創建的只有一個部門專業或組專業也創建,例如,您可以撤消所有已實施的基表和VIEW的所有寫入權限,並強制用戶創建專業使用您編碼的CRUD程序,以確保始終滿足超級/子類型要求。

+0

這絕對是一種選擇。將給它一個測試運行。感謝 – DanM 2012-03-14 19:28:48

1

您可以創建一個「空剋星」計算列的基礎上,可爲空GroupID列,並使其成爲PK的一部分,而不是GroupID

create table Specialities (
    CompanyID varchar(10) not null, 
    DivisionID int not null, 
    DepartmentID int not null, 
    GroupID int null, 
    SpecialityID int not null, 
    Name varchar(10) not null, 
    Description varchar(max) not null, 
    _NNGroupID as ISNULL(GroupID,-1), 
    constraint PK_Specialities PRIMARY KEY (CompanyID,DivisionID,DepartmentID,_NNGroupID,SpecialityID) 
) 

我不知道我是否喜歡這個想法與否,但它可能是你的選擇。這假設沒有-1的實際GroupID將永遠存在 - 你可能不得不爲你的目的選擇一個不同的魔術值。只要ISNULL右側的值不是實際GroupID的域的一部分,就應該有效。

您繼續根據GroupID而不是_NNGroupID定義外鍵,以便外鍵約束的可空性如您所期望的那樣工作。

+0

這聽起來像是一個不錯的選擇,但我如何將這與ADO.Net實體框架對齊呢? – DanM 2012-03-14 19:27:05

+0

我還沒有試圖自己實現這樣的映射 - 我可以提供關於純SQL的建議,但它如何與ORM一起工作對我來說是一個謎 - 我仍然嘗試直接編寫大部分SQL。 – 2012-03-14 19:32:15

+0

謝謝;如果我找出一種管理方法,我會仔細研究併發布。 – DanM 2012-03-14 20:11:51

相關問題