2011-06-26 228 views
2

工作人員只能有一輛車,車輛一次只能屬於一名工人。 有3層可能的實現我知道:
1.1對1關係

Vehicle(Id, Number) 
Worker(Id, Name, VehicleId) 
--> This allows two workers have the same vehicle. 

2.

Worker(Id, Name) 
Vehicle(Id, Number, WorkerId) 
--> This allows worker to have two vehicles. 

3.

Worker(Id, Name) 
    Vehicle(Id, Number) 
    WorkersVehicles(Id, VehicleId, WorkerId) 
    --> This allows each worker to have many vehicles and each vehicle to belong to many workers. 

以上都不可以描述所期望的1:1的關係。

如何在數據庫和實體框架中描述這種1:1關係?

+0

難道工人必須有車? – awright18

回答

3

定義數據模型只通過約束強制1:1關係是不可能的,因爲這需要一個循環引用,這意味着你將永遠無法插入關係的一邊,直到另一邊存在。

雖然有可能通過欺騙來解決這個問題(刪除約束,使用特定於RDBMS的命令,如Oracle的延遲約束),但傳統意義上不可能這樣做。你可以得到最接近的是1:0..1

以下是代表的Worker:Vehicle各種組合型號:

0..1:1

Worker (ID, VehicleID unique constraint) 
Vehicle (ID) 

1:0..1

Worker (ID) 
Vehicle (ID, WorkerID unique constraint) 

0..1:0..1

Worker (ID) 
Vehicle (ID) 
WorkerVehicle (WorkerID, VehicleID) <-- primary key on one column, 
             unique constraint on the other 

不幸的是,由於EF不支持唯一的約束(或者說,它不能識別或強制它們),所以你總是會在關係的另一端得到一個集合,而不是一個實體。

-1

這種東西可以在數據庫或代碼中處理。如果你用代碼來做,那麼只需在創建一條規則,然後試圖持續檢查車輛是否屬於另一名工人。如果這樣拋出一個異常。如果您選擇在數據庫中添加規則,那麼應該在表中包含外鍵的觸發器中完成,這將再次檢查車輛是否屬於另一名工作人員,如果它確實應該提出一個錯誤。不應該使用實體框架來處理業務邏輯。

1

由於@Adam說明你需要FK獨特的強制執行一到一個關係,因爲EF不支持唯一的約束還沒有使這個在EF的唯一途徑是:

Worker(ID) 
Vehicle(ID) <-- PK and FK to worker 

配售FK到PK將強制執行唯一性。解決方法是使用:

Worker(ID) 
Vehicle(ID, WorkerID) <-- WorkerID is FK with unique constraint in the database 

一旦被映射到EDMX你會從Worker刪除Vehicles導航屬性。如果您將一輛車分配給兩名工人,數據庫將拋出異常。此解決方法的缺點是您無法從工作人員訪問車輛(您沒有導航屬性)。

反正一到一個關係是罕見的 - 它應主要用於「是一個」爲「有-A」的情況多了一個罕見。在某些情況下,我認爲這是合理使用一個一對多的,而不是一個對一個,並在應用程序邏輯控制驗證。如果在未來添加新的相關實體的主要需求變化將只是一個不斷變化的驗證,而不是改變應用程序的一半的問題。你可以決定這是否是你的情況。