2011-06-26 136 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”的情况多了一个罕见。在某些情况下,我认为这是合理使用一个一对多的,而不是一个对一个,并在应用程序逻辑控制验证。如果在未来添加新的相关实体的主要需求变化将只是一个不断变化的验证,而不是改变应用程序的一半的问题。你可以决定这是否是你的情况。