如何使用 EF Core 3.1 将 IEnumerable<string> 的属性存储在 Cosmos 表中

Nei*_*eil 5 entity-framework-core .net-core azure-cosmosdb

我的项目使用 EF Core 3.1,并以 Azure Cosmos 作为数据库。

我有一个这样的实体:

public class MyEntity
{
    public IEnumerable<string> Names {get;set;}
    ... other fields
}
Run Code Online (Sandbox Code Playgroud)

我希望最终得到这样的 Cosmos 文档:

{
    "Names": ["Name1", "Name2"]
}
Run Code Online (Sandbox Code Playgroud)

对于实体 ( IEnumerable<string>) 我收到错误:

无法映射属性“MyEntity.Names”,因为它的类型为“IEnumerable”,该类型不是受支持的基元类型或有效的实体类型。

如果我将实体更改为:

public class NameEntity
{
    public string Name {get;set;}
}
public class MyEntity
{
    public IEnumerable<NameEntity> Names {get;set;}
    ... other fields
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<MyEntity>(e =>
    {
        e.OwnsMany(p => p.Identifiers);
    });
}
Run Code Online (Sandbox Code Playgroud)

该文档如下所示:

{
    "Id": "XXXXXX",
    "Names:" [
       {},
       {}
    ],
}
Run Code Online (Sandbox Code Playgroud)

所以我改变了OnModelCreating:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<MyEntity>(e =>
    {
        e.OwnsMany(p => p.Identifiers, o=> o.HasKey(k=>k.Name));
    });
}
Run Code Online (Sandbox Code Playgroud)

然后我得到:

{
  "Names": [
    {
        "Name": "<string1>",
        "Id": "XXXX"
    },
    {
        "Identifier": "<string2>",
        "Id": "XXXX"
    }
]}
Run Code Online (Sandbox Code Playgroud)

我还研究了值转换器,但我认为这更多的是用于在类型之间转换属性值,而不是将实体转换为字符串。

任何帮助,将不胜感激。

小智 1

这是与您类似的问题:Entity Framework - Code First - Can't Store List<String>

目前,无法存储原始类型(包括字符串)的列表。

最好的选择是将列表作为字符串存储在数据库中,当您获取它时,将其转换回列表。

正如上面的链接所解释的,您可以在 OnModelCreating 方法中执行以下操作:

modelBuilder.Entity<YourEntity>()
        .Property(e => e.Strings)
        .HasConversion(
            v => string.Join(',', v),
            v => v.Split(',', StringSplitOptions.RemoveEmptyEntries));
Run Code Online (Sandbox Code Playgroud)