使用带有EF Core的Cosmos DB查询标签

时间:2020-11-04 08:51:12

标签: .net-core entity-framework-core azure-cosmosdb

我有一个与EF Core和Cosmos DB提供程序一起保留的域模型。问题是,我想向其中添加标签,我想查询该标签,例如,返回所有具有此标签的条目。不幸的是,Cosmos DB不支持字符串数组(以及其他),所以我只能想象使用单个字符串属性,这远非理想,因为如果我需要多个标签,则需要将它们组合在同一个属性上,可能是分开的用空格隔开,这将使查询单个空格非常困难。实现此目标的最佳选择是什么?

2 个答案:

答案 0 :(得分:0)

这是EF Core(不是Cosmos DB)的限制-禁止具有字符串数组属性的实体。 为了解决这个问题,我只使用了Cosmos DB API并删除了EF Core。

答案 1 :(得分:0)

您可以创建一个 POCO:

public class Tag
{
    public string Name { get; set; }
}

然后你的模型类看起来像这样:

public class MyEntity
{
    public string Id { get; set; }
    public string Name { get; set; }
    public List<Tag> Tags { get; set; }
}

通过覆盖 OnModelCreating() 或使用单独的配置文件来指示 EF 如何处理模型:

// Configure the one-to-many/owns many relationship:
builder
   .OwnsMany(
      ownedType: typeof(Tag),
      navigationName: nameof(MyEntity.Tags))
   .WithOwner();

这将产生如下内容:

{
    "Id": "some-unique-id",
    "Name": "The name of the entity",
    "Tags": [
        {
            "Name": "Developer"
        },
        {
            "Name": "Hacker"
        },
        {
            "Name": "Guru"
        } 
    ]
}

或者,您可以像这样定义一个简单的转换:

builder.Property(c => c.Tags)
    .HasConversion(
        v => string.Join(',', v),
        v => v.Split(',', StringSplitOptions.RemoveEmptyEntries).ToList()
    );

这将允许根据需要查询字符串列表,但在数据库中作为逗号分隔的字符串值被持久化。虽然这可能没问题,但您会在 Cosmos Db 中失去一些查询能力。

注意:您可能还需要实现比较器,以便 EF 正确跟踪更改。