Cosmos Db 和 EF Core:System.InvalidOperationException:无法跟踪“Order”类型的实体,因为其主键属性“Id”为 null

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

所以我一直在使用 CosmosClient 来开发我的应用程序,但我想实现 CosmosClient 不支持的域事件,所以我不得不切换到 EF Core。使用 EF Core 时,我无法从数据库获取实体,因为 Id 在 cosmos 中保存为“id”。

我尝试使用 JsonProperty("id")、Column("id") 以及 AsNoTracking,但都给出相同的结果。我该怎么办?

我的 BaseEntity 类:

public abstract class BaseEntity
{
    [JsonProperty("id")] 
    [Column("id")]
    public virtual string Id { get; set; } = Guid.NewGuid().ToString();
    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
    public DateTime? ModifiedAt { get; set; }
}

我的 COMOSDb 文档:

{
    "OrderNumber": "1000000000",
    "PatientData": {
        ...
    },
    "Results": {
        ...
    },
    "Status": 2,
    "id": "1000000000",
    "CreatedAt": "2024-03-21T17:58:50.432892+01:00",
    "ModifiedAt": "2024-03-24T01:24:17.52464Z",
    "_rid": "7NA1AKlBYQ8MAAAAAAAAAA==",
    "_self": "dbs/7NA1AA==/colls/7NA1AKlBYQ8=/docs/7NA1AKlBYQ8MAAAAAAAAAA==/",
    "_etag": "\"0000a702-0000-5600-0000-65ff80c10000\"",
    "_attachments": "attachments/",
    "_ts": 1711243457
}
c# asp.net .net entity-framework azure-cosmosdb
1个回答
0
投票

Cosmos Db 和 EF Core:System.InvalidOperationException:无法跟踪“Order”类型的实体,因为其主键属性“Id”为 null

上述错误主要发生在 Entity Framework Core 尝试跟踪主键为空的实体或 EF Core 未正确将 Cosmos DB 文档中的

id
属性映射到 Order 实体的
Id
属性时。下面的代码主键不为 null,它将 Cosmos DB 文档的
id
属性映射到
Order
实体的
Id
属性。

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

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseCosmos(
            "AccountEndpoint=https://<acc_name>.documents.azure.com:443/;AccountKey=<primary_key>", "firstDb");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Order>()
            .ToContainer("secondCont")
            .HasPartitionKey(o => o.Id); 

        modelBuilder.Entity<Order>()
            .Property(o => o.Id)
            .ToJsonProperty("id");
    }

    public async Task InsertOrderAsync(Order order)
    {
        await Orders.AddAsync(order);
        await SaveChangesAsync();
    }
}

public class Order : BaseEntity
{
    public string OrderNumber { get; set; }
}

public abstract class BaseEntity
{
    [JsonProperty("id")]
    public virtual string Id { get; set; } = Guid.NewGuid().ToString();
    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
    public DateTime? ModifiedAt { get; set; }
}

class Program
{
    static async Task Main(string[] args)
    {
        using (var context = new YourDbContext())
        {
            var newOrder = new Order
            {
                OrderNumber = "10000001",
            };

            await context.InsertOrderAsync(newOrder);
            Console.WriteLine("New order inserted successfully.");
        }
    }
}

在上述代码中,

Order
实体将映射到名为
"secondCont"
的 Cosmos DB 容器,并将
Id
实体的
Order
属性映射到 Cosmos DB 文档中名为
"id"
的 JSON 属性。

输出:

New order inserted successfully.

在 Cosmos DB 中保存的项目:

{
    "id": "c7613229-6d72-4b6b-b29c-9673be54cdde",
    "CreatedAt": "2024-04-27T12:24:55.3344193Z",
    "Discriminator": "Order",
    "ModifiedAt": null,
    "OrderNumber": "10000001"
}
© www.soinside.com 2019 - 2024. All rights reserved.