如何使用 Azure Cosmos Db 对 EF Core 中的数据进行非规范化?

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

如本文档所示:https://learn.microsoft.com/en-us/azure/cosmos-db/nosql/model-partition-example#v2-introducing-denormalization-to-optimize-read-queries

我需要对也位于另一个容器中的实体进行非规范化:

public class Post
{
       public int Id { get; set; }
       public string Title { get; set; } = null!;
       public List<Hashtag> Hashtags { get; set; } = new List<Hashtag>();
}

public class Comment
{
       public int Id { get; set; }
       public int PostId { get; set; }
       public string Text { get; set; } = null!;
       public List<Hashtag> Hashtags { get; set; } = new List<Hashtag>();
}

public class Hashtag
{
       public int Id { get; set; }
       public string Title { get; set; } = null!;
       public int Puntuation { get; set; }
}

因此,为了更快的查询,我需要将

Hashtag
嵌入到
Comment
Post
中(这只是一个示例,不是真正的用例),但主题标签位于它自己的容器中。

我知道这在 EF Core 中是不可能的,因为我会看到这样的错误:

“主题标签”类型无法标记为拥有,因为已存在同名的非拥有实体类型。

有什么解决办法吗?

我尝试过做这样的事情:

builder.Entity<Post>().ToContainer("Post");
builder.Entity<Post>().OwnsMany(p => p.Hashtags);

builder.Entity<Comment>().ToContainer("Post");
builder.Entity<Comment>().OwnsMany(p => p.Hashtags);

builder.Entity<Hashtag>().ToContainer("Hashtag");
c# .net entity-framework-core azure-cosmosdb azure-cosmosdb-sqlapi
1个回答
0
投票

如何使用 Azure Cosmos Db 对 EF Core 中的数据进行非规范化?

下面是有关如何使用 Azure Cosmos DB 对 EF Core 中的数据进行非规范化的示例。其中

Order
实体包含嵌套实体
Customer
OrderDetail
。在
OnModelCreating
方法中,设置实体配置来定义实体在 Cosmos DB 中的存储方式。
OwnsOne
OwnsMany
方法用于指定所有权和配置嵌套实体。使用
HasData
方法将样本数据植入数据库。该数据包括
Order
实体及其关联的
Customer
OrderDetail
实体。非规范化是通过将相关数据分组到单个文档或容器中来执行的,如下面的输出所示。

public class Order
{
    public string id { get; set; }
    public DateTime OrderDate { get; set; }
    public Customer Customer { get; set; }
    public List<OrderDetail> OrderDetails { get; set; }
}

public class Customer
{
    public string CustomerId { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
}

public class OrderDetail
{
    public string Id { get; set; }  
    public string OrderId { get; set; } 
    public string ProductId { get; set; }
    public string ProductName { get; set; }
    public decimal ProductPrice { get; set; }
    public int Quantity { get; set; }
}

public class ECommerceContext : DbContext
{
    public DbSet<Order> Orders { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseCosmos(
            "<url>",
"<primary_key>",
            databaseName: "firstDb");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Order>()
            .OwnsOne(o => o.Customer, customer =>
            {
                customer.WithOwner().HasForeignKey("OrderId");
                customer.Property<string>("CustomerId").IsRequired();
            });

        modelBuilder.Entity<Order>().OwnsMany(o => o.OrderDetails, od =>
        {
            od.WithOwner().HasForeignKey("OrderId");
            od.Property<string>("Id").IsRequired(); // Ensure Id is required
        });

        modelBuilder.Entity<Order>()
            .ToContainer("Orders")
            .HasPartitionKey(o => o.id);

        // Seeding the Order entity
        modelBuilder.Entity<Order>().HasData(new Order
        {
            id = "order1",
            OrderDate = DateTime.UtcNow
        });

        // Seeding related Customer entity
        modelBuilder.Entity<Order>().OwnsOne(o => o.Customer).HasData(new
        {
            OrderId = "order1",
            CustomerId = "customer1",
            Name = "Pavan Sai",
            Email = "[email protected]"
        });

        // Seeding related OrderDetail entities
        modelBuilder.Entity<Order>().OwnsMany(o => o.OrderDetails).HasData(
            new
            {
                Id = "orderdetail1",
                OrderId = "order1",
                ProductId = "product1",
                ProductName = "Product 1",
                ProductPrice = 10.0m,
                Quantity = 2
            },
            new
            {
                Id = "orderdetail2",
                OrderId = "order1",
                ProductId = "product2",
                ProductName = "Product 2",
                ProductPrice = 20.0m,
                Quantity = 1
            }
        );
    }
}

输出:

List of Orders:
Order ID: order1
Order ID: order1
Order Date: 5/29/2024 10:06:45 AM
Customer ID: customer1
Customer Name: Pavan Sai
Customer Email: [email protected]
  Product ID: product1
  Product Name: Product 1
  Product Price: $10.00
  Quantity: 2
  Product ID: product2
  Product Name: Product 2
  Product Price: $20.00
  Quantity: 1
© www.soinside.com 2019 - 2024. All rights reserved.