如何在 EF Core 中为拥有的 JSON 列添加注释?

问题描述 投票:0回答:2

给定一个 EF Core 实体,其拥有的类型存储在 JSON 列中,就像这样

public class MyEntity
{
  public MyEntity( SomeMetadata metadata) : this()
  {
    Metadata = metadata;
  }

  /// <summary>
  /// Just for EntityFramework because it can't handle a constructor with owned type.
  /// </summary>
  private MyEntity()
  {
  }

  public Guid PrimaryId { get; private set; }

  public SomeMetadata Metadata { get; private set; }

  public class SomeMetadata
  {
    public string? SomeNestedThing { get; set; }
  }
}


public class MyEntityConfiguration : IEntityTypeConfiguration<MyEntity>
{
  public void Configure(EntityTypeBuilder<MyEntity> builder)
  {
    builder.OwnsOne(e => e.Metadata, ownedNavigationBuilder =>
    {
      ownedNavigationBuilder.ToJson();
    });

    builder.Property(e => e.Metadata)
      .HasComment("Comment about this JSON column");
  }
}

尝试使用

HasComment
创建迁移时,
dotnet ef migrations add
调用将导致失败。给出的信息是

System.InvalidOperationException:“元数据”不能用作实体类型“MyEntity”的属性,因为它被配置为导航。

我理解,之所以这样,大概是因为如果明天我选择把这个

Metadata
存到一个单独的表中,那我就不能再有“列评论”了。我怎样才能覆盖它并添加评论?

我唯一想到的是手动编辑迁移以添加评论,但这意味着如果我们以后想编辑评论,我们必须再次手动编辑它,所以我会更愿意让 EF Core 为我们生成指令。

c# entity-framework owned-types
2个回答
0
投票

Metadata
不是表中的一列,它是一个导航属性,它应该指向另一个表中包含您所需信息的记录。

但是,在您的场景中,您实际上并不需要导航属性。你可以调整你的代码,使“JSON”列是一个字符串。

public MyEntity(SomeMetadata metadata) : this()
{
    Metadata = metadata.SomeNestedThing;
}

public string Metadata { get; private set; }

0
投票

解决此问题的一种方法是为拥有的类型创建一个单独的配置,并改为在该配置中设置属性的注释。

这是一个如何向 JSON 列添加注释的示例:

public class MyEntityConfiguration : IEntityTypeConfiguration<MyEntity>
{
    public void Configure(EntityTypeBuilder<MyEntity> builder)
    {
        builder.OwnsOne(e => e.Metadata, metadataBuilder =>
        {
            metadataBuilder.Property(p => p.SomeNestedThing).HasComment("Comment about this JSON column");
            metadataBuilder.ToJson();
        });
    }
}

我们将 SomeMetadata 类型与 MyEntity 类型分开配置。我们在 SomeMetadata 类型的 SomeNestedThing 属性上设置注释,这应该有效,因为此属性未配置为导航属性。

© www.soinside.com 2019 - 2024. All rights reserved.