EF core cosmos 外键

问题描述 投票:0回答:1

我正在使用 EF 核心和 Azure Cosmos DB。我的外键有问题。 当我加载一个实体时,没有加载相关的类。 例如,我想选择一个用户及其角色。它连接到用户、租户和角色容器。数据已加载,但关系未加载:

我尝试了不同的一对一/一对多关系。 关系的最后配置是:

var tenantUserModel = modelBuilder.Entity<TenantUser>();
            tenantUserModel.ToContainer(nameof(TenantUsers))
                .HasNoDiscriminator()
                .HasPartitionKey(tu => tu.TenantId)
                .HasKey(tu => new {tu.TenantId,tu.UserId,tu.RoleId});
tenantUserModel.HasOne(tu => tu.User).WithMany().HasForeignKey(tu=>tu.UserId);

但它不会加载关系。

entity-framework-core azure-cosmosdb
1个回答
0
投票

Cosmos DB 不是 关系数据库。尽管有一个 SQL API 和关系数据库用户熟悉的查询语法,但不可能连接实体。没有关系和外键这样的概念,这就是为什么使用 Cosmos DB 时不支持

Include
等 EF Core 功能的原因。

Cosmos DB 存储 JSON 文档。文档存储在容器中,容器被组织成数据库。文档没有固定的架构,因此您可以将不同的文档类型存储在同一个容器中。 EF Core 通过在 JSON 文档中使用指定文档类型的鉴别器来支持这一点。

有物理服务器存储容器的内容,即 JSON 文档。然而,为了支持水平可伸缩性,容器可以分布在多个物理服务器(实际上是服务器集群)上。每个 JSON 文档都有一个分区键,这个键决定给定 JSON 文档存储在哪个服务器分区上。

您通常从单个服务器分区开始,但随着数据的增长,它可以拆分为多个服务器分区。这是完全透明的,没有停机时间,所以规则是,如果两个文档没有相同的分区键,可以说它们生活在不同的世界中。您不能请求 Cosmos DB 加入它们,因为它们可能位于不同的服务器上,并且 Cosmos DB 的可扩展性和性能特性取决于仅限于在单个服务器(好吧,单个服务器集群)上运行的操作。

另一方面,如果两个或多个文档具有相同的分区键,它们将始终存储在同一台服务器上,在这种情况下,Cosmos DB 支持一些附加功能,例如访问多个文档的存储过程(编写起来很乏味)和批处理操作(有点像交易)。但是,这在 EF Core 中不可用。

底线:您不能将关系模型改造为 Cosmos DB。如果您需要 Cosmos DB 的功能,则必须设计整个应用程序才能使用它。如何?好吧,这在很大程度上取决于您的应用程序。如果您的数据可以组织成层次模型(例如父、子、孙),那么您可以将每个图形存储为单个文档,避免规范化数据和引入关系仅为满足数据库需求的复杂性。但是,如果您的数据确实是相关的,并且您需要构建许多不同的图形和聚合,那么您可以构建一个系统,在该系统中捕获一个容器中的传入更改,然后使用 Cosmos DB 更改将此源数据投影到其他容器中的物化视图喂养。如果你眯着眼睛看,它可能看起来像事件溯源和实时流。

© www.soinside.com 2019 - 2024. All rights reserved.