Given an EF Core entity with an owned type that's stored in a JSON column like so
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");
}
}
The HasComment
call will result in a failure when trying to create a migration using dotnet ef migrations add
. The message given is
System.InvalidOperationException: 'Metadata' cannot be used as a property on entity type 'MyEntity' because it is configured as a navigation.
I understand that the reason for this is probably because if tomorrow I choose to store this Metadata
in a separate table, then I can't have a "column comment" anymore. How can I go about overriding this and adding a comment?
The only thing I've come up with is editing the migration manually to add a comment, but this means that if we want to edit a comment later in the future, we'd have to manually edit it again, so I'd prefer to let EF Core generate the instruction for us.
Metadata
is not a column in a table, it is a navigation property, which should point to a record in another table that holds your desired info.However, in your scenario, you don't really need a navigation property. You can just adjust your code so that the "JSON" column is a string.
After these changes,
Metadata
will be an actual column in the table and your code for adding the comment will work.