【问题标题】:1 to 1 relationship1对1关系
【发布时间】:2011-06-26 02:01:31
【问题描述】:

工人只能拥有一辆车,车辆一次只能属于一名工人。 我知道有 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 关系?

【问题讨论】:

  • 工人必须有车吗?

标签: c# .net entity-framework


【解决方案1】:

定义一个仅通过约束强制执行 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 不支持唯一约束(或者,更确切地说,它不识别或强制执行它们),您将始终在关系的另一端得到一个集合,而不是单个实体。

【讨论】:

    【解决方案2】:

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

    根据这个 SO 帖子How can I add constraints to an ADO.NET Entity?,EF 似乎不直接支持唯一约束

    【讨论】:

      【解决方案3】:

      正如@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 导航属性。如果您将一辆车分配给两个工人数据库将抛出异常。此解决方法的缺点是您无法从工作人员访问车辆(您没有导航属性)。

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-07-08
          • 1970-01-01
          • 2023-04-06
          • 1970-01-01
          • 1970-01-01
          • 2017-09-22
          • 1970-01-01
          • 2011-08-26
          相关资源
          最近更新 更多