使用 Cosmos DB 配置 EF Core 以存储字符串的 ICollection
Configure EF Core with Cosmos DB to store ICollection of string
Entity framework 有一些关于 Embedding entities 的不错的文档,但我不知道如何嵌入一个简单的字符串数组 IEnumerable<string>
.
样本class
public class Post {
public string Id {get;set;}
public string Content {get;set;}
public IEnumerable<string> Tags {get;set;}
}
这应该在 cosmos 中保存为:
{
"id": "xxx",
"content": "long content here",
"tags": ["tag1", "tag2"],
...
}
我知道我必须在 Context 的 OnModelCreating(ModelBuilder modelBuilder)
中配置一些东西。但是我无法正确设置它。
我尝试了以下选项(以及其他几种 ToJsonProperty
方法):
modelBuilder.Entity<Post>().OwnsMany(p => p.Tags);
modelBuilder.Entity<Post>().OwnsMany<string>(p => p.Tags);
最终我希望能够根据这些标签进行查询,非常感谢任何帮助或正确方向的指示!
我也找到了 this answer 但是将数组转换为逗号分隔的字符串会破坏目的(因为这不允许我们查询那些帖子)。
其他人 asked 在 Microsoft 论坛上提出大致相同的问题,其中一位 Microsoft 员工表示在纯 CosmosDB 中可以在 cosmos 中嵌入字符串数组。
我发现 github issue 在 Cosmos 的 EF 核心提供商处跟踪此问题。
所以官方的回答是,目前不支持。至少在上述问题关闭之前。
更新,2021 年 7 月,EfCore 6.0.0 似乎现在支持此功能
我最近试图找到同一个问题的答案。没有找到很好的解决方案,所以我创建了一个新模型
public class Tag
{
public string Name { get; set; }
}
public class Post
{
...
public IEnumerable<Tag> Tags { get; set; }
}
...
modelBuilder.Entity<Post>().OwnsMany(p => p.Tags);
在您的模型构建器中使用这样的值转换器:
modelBuilder.Entity<Post>().Property(p => p.Tags).HasConversion(v => JsonConvert.SerializeObject(v), v => JsonConvert.DeserializeObject<List<string>>(v));
使用这样的值转换器:
public class TagsValueConverter : ValueConverter<IReadOnlyCollection<string>, string[]>
{
public TagsValueConverter() : base(
value => value.ToArray(),
dbValue => dbValue.ToList())
{
}
}
Entity framework 有一些关于 Embedding entities 的不错的文档,但我不知道如何嵌入一个简单的字符串数组 IEnumerable<string>
.
样本class
public class Post {
public string Id {get;set;}
public string Content {get;set;}
public IEnumerable<string> Tags {get;set;}
}
这应该在 cosmos 中保存为:
{
"id": "xxx",
"content": "long content here",
"tags": ["tag1", "tag2"],
...
}
我知道我必须在 Context 的 OnModelCreating(ModelBuilder modelBuilder)
中配置一些东西。但是我无法正确设置它。
我尝试了以下选项(以及其他几种 ToJsonProperty
方法):
modelBuilder.Entity<Post>().OwnsMany(p => p.Tags);
modelBuilder.Entity<Post>().OwnsMany<string>(p => p.Tags);
最终我希望能够根据这些标签进行查询,非常感谢任何帮助或正确方向的指示!
我也找到了 this answer 但是将数组转换为逗号分隔的字符串会破坏目的(因为这不允许我们查询那些帖子)。
其他人 asked 在 Microsoft 论坛上提出大致相同的问题,其中一位 Microsoft 员工表示在纯 CosmosDB 中可以在 cosmos 中嵌入字符串数组。
我发现 github issue 在 Cosmos 的 EF 核心提供商处跟踪此问题。
所以官方的回答是,目前不支持。至少在上述问题关闭之前。
更新,2021 年 7 月,EfCore 6.0.0 似乎现在支持此功能
我最近试图找到同一个问题的答案。没有找到很好的解决方案,所以我创建了一个新模型
public class Tag
{
public string Name { get; set; }
}
public class Post
{
...
public IEnumerable<Tag> Tags { get; set; }
}
...
modelBuilder.Entity<Post>().OwnsMany(p => p.Tags);
在您的模型构建器中使用这样的值转换器:
modelBuilder.Entity<Post>().Property(p => p.Tags).HasConversion(v => JsonConvert.SerializeObject(v), v => JsonConvert.DeserializeObject<List<string>>(v));
使用这样的值转换器:
public class TagsValueConverter : ValueConverter<IReadOnlyCollection<string>, string[]>
{
public TagsValueConverter() : base(
value => value.ToArray(),
dbValue => dbValue.ToList())
{
}
}