实体框架和多租户数据库设计

Reb*_*cca 7 database-design entity-framework saas multi-tenant

我正在研究SaaS概念的多租户数据库模式设计.它将是ASP.NET MVC - > EF,但这并不是那么重要.

您可以在下面看到示例数据库架构(租户是公司).在整个架构中复制CompanyId,并且主键已放置在自然键和租户ID上.

当我将表添加到实体模型文件(Model1.edmx)时,将此模式插入实体框架会产生以下错误:

  • 关系'FK_Order_Customer'使用一组外键'{CustomerId,CompanyId}',它们部分包含在'Order'表的主键'{OrderId,CompanyId}'中.外键集必须完全包含在主键集中,或者完全不包含在要映射到模型的主键集中.
  • 关系'FK_OrderLine_Customer'使用部分包含在'OrderLine'表的主键'{OrderLineId,CompanyId}'中的外键'{CustomerId,CompanyId}'.外键集必须完全包含在主键集中,或者完全不包含在要映射到模型的主键集中.
  • 关系'FK_OrderLine_Order'使用部分包含在'OrderLine'表的主键'{OrderLineId,CompanyId}'中的外键'{OrderId,CompanyId}'.外键集必须完全包含在主键集中,或者完全不包含在要映射到模型的主键集中.
  • 关系'FK_Order_Customer'使用一组外键'{CustomerId,CompanyId}',它们部分包含在'Order'表的主键'{OrderId,CompanyId}'中.外键集必须完全包含在主键集中,或者完全不包含在要映射到模型的主键集中.
  • 关系'FK_OrderLine_Customer'使用部分包含在'OrderLine'表的主键'{OrderLineId,CompanyId}'中的外键'{CustomerId,CompanyId}'.外键集必须完全包含在主键集中,或者完全不包含在要映射到模型的主键集中.
  • 关系'FK_OrderLine_Order'使用部分包含在'OrderLine'表的主键'{OrderLineId,CompanyId}'中的外键'{OrderId,CompanyId}'.外键集必须完全包含在主键集中,或者完全不包含在要映射到模型的主键集中.
  • 关系'FK_OrderLine_Product'使用部分包含在'OrderLine'表的主键'{OrderLineId,CompanyId}'中的外键'{ProductId,CompanyId}'.外键集必须完全包含在主键集中,或者完全不包含在要映射到模型的主键集中.

问题分为两部分:

  1. 我的数据库设计不正确吗?我应该避免使用这些复合主键吗?我正在质疑我对基本模式设计(疲惫的大脑综合症)的理智.请随意提出"理想化"架构.
  2. 或者,如果数据库设计正确,那么EF无法匹配密钥,因为它将这些外键视为潜在的错误配置的1:1关系(错误)?在这种情况下,这是一个EF错误,我该如何解决它?

多租户数据库架构http://i46.tinypic.com/23si52u.png

Cyl*_*Cat 4

快速浏览一下 EF 的错误消息,它显然不喜欢您设置复合键的方式,我认为它可能会引导您走向正确的方向。再次思考一下是什么让你的主键独一无二。如果没有 CompanyID,OrderID 是否唯一?如果没有 CompanyID,ProductID 是否不唯一?在没有 CompanyID 的情况下,OrderLine 当然应该是唯一的,因为 OrderLine 应该仅与单个订单相关联。

如果您确实需要所有这些的 CompanyID,这可能意味着相关公司正在向您提供 ProductID 和 OrderID,那么您可能需要采取不同的方向,并生成您自己的非数据固有的主键。只需为主键设置一个自增列,并将其设置为内部 OrderID、OrderLineID、ProductID、CompanyID 等。此时,OrderLine 将不需要客户的 OrderID 或 CompanyID;对订单的外键引用将是其起点。(并且 CustomerID 永远不应该是订单行的属性;它是订单的属性,而不是订单行的属性。)

复合键太乱了。尝试在没有它们的情况下设计模型,看看它是否可以简化事情。