1比1的关系

时间:2011-06-26 02:01:32

标签: c# .net entity-framework

工人只能拥有一辆车,而车辆一次只能属于一名工人。 我知道有3种可能的实施方式:
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关系?

4 个答案:

答案 0 :(得分: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)

您可能需要使用unique constraint表示员工必须拥有唯一的VehicleId

根据此SO How can I add constraints to an ADO.NET Entity?

,EF似乎并不直接支持唯一约束

答案 2 :(得分: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后,您将从Vehicles中删除Worker导航属性。如果将一辆车分配给两个工人,数据库将抛出异常。此解决方法的缺点是您无法从工作人员访问车辆(您没有导航属性)。

无论如何,一对一的关系很少见 - 它应该主要用于“is-a”,更少用于“has-a”场景。在某些情况下,我认为在应用程序逻辑中使用一对多而不是一对一并控制验证是合理的。如果将来需求更改,则向主体添加新的相关实体将只是更改验证而不是更改应用程序的一半。你可以决定这是否属于你的情况。

答案 3 :(得分:-1)

这种事情可以在数据库或代码中处理。如果您在代码中执行此操作,则只需创建规则,然后再尝试保留对象,以检查车辆是否属于另一个工作程序。如果是这样抛出异常。如果您选择在数据库中添加规则,那么应该在包含外键的表的触发器中完成,这将再次检查车辆是否属于另一个工作人员,如果它是应该引发错误。不应使用实体框架来处理业务逻辑。