使用Cosmos DB配置EF Core以存储字符串的ICollection



Entity框架有一些关于嵌入实体的不错的文档,但我不知道如何嵌入一个简单的字符串数组IEnumerable<string>

样品类别

public class Post {
public string Id {get;set;}
public string Content {get;set;}
public IEnumerable<string> Tags {get;set;}
}

这应该保存在宇宙中作为:

{
"id": "xxx",
"content": "long content here",
"tags": ["tag1", "tag2"],
...
}

我知道我必须在上下文的OnModelCreating(ModelBuilder modelBuilder)中配置一些内容。但我无法正确设置它。

我尝试了以下选项(以及其他几种ToJsonProperty方法(:

  • modelBuilder.Entity<Post>().OwnsMany(p => p.Tags);
  • modelBuilder.Entity<Post>().OwnsMany<string>(p => p.Tags);

最终,我希望能够基于这些标签进行查询,非常感谢任何正确方向的帮助或指针!

我也找到了这个答案,但将数组转换为逗号分隔的字符串会破坏目的(因为这不允许我们查询这些帖子(。

还有人在微软论坛上提出了大致相同的问题,一名微软员工表示,在纯宇宙数据库中,可以在宇宙中嵌入字符串数组。

我最近试图找到同一个问题的答案。没有找到一个好的解决方案,所以我创建了一个新的模型

public class Tag
{
public string Name { get; set; }
}
public class Post
{
...
public IEnumerable<Tag> Tags { get; set; }
}
...
modelBuilder.Entity<Post>().OwnsMany(p => p.Tags);

我在Cosmos的EF核心提供商处发现了一个跟踪此问题的github问题。

因此官方的答案是,这是目前不支持的。至少在上述问题结束之前。

更新,2021年7月,这似乎现在在EfCore 6.0.0 中得到支持

使用这样的值转换器:


public class TagsValueConverter : ValueConverter<IReadOnlyCollection<string>, string[]>
{
public TagsValueConverter() : base(
value => value.ToArray(),
dbValue => dbValue.ToList())
{
}
}

在您的模型构建器中使用这样的值转换器:

modelBuilder.Entity<Post>().Property(p => p.Tags).HasConversion(v => JsonConvert.SerializeObject(v), v => JsonConvert.DeserializeObject<List<string>>(v));

最新更新