所以我一直在使用 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
}
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"
}