Please support Json nested name convertions.
ye4241 opened this issue · 3 comments
I noticed that there is a TODO in code:
Could you please add feature for this?
foreach (var property in entityType.GetProperties())
{
property.Builder.HasNoAnnotation(RelationalAnnotationNames.ColumnName);
property.Builder.HasJsonPropertyName(_namingNameRewriter.RewriteName(property.GetColumnName()));
}
As the comment says, I doubt this is something that a lot of people actually want - the naming conventions inside JSON documents is usually unrelated to the naming conventions of database columns. I'll put this in the backlog for now to gather more feedback/votes.
@ye4241 for your information, I encountered exactly the same problem and searched few hours how to solve it. It's quite sad the plugin EFCore.NamingConventions doesn't take it (at least with a parameter) but you can find my solution below :
- Create a stringExtension to be able to convert to your defined convention (in my case, camelCase) :
public static class StringExtension
{
public static string ToCamelCase(this string? text)
{
if (string.IsNullOrEmpty(text))
{
return string.Empty;
}
//If text is in snake_case, convert each word inside to camelCase
if (text.Contains('_'))
{
var newText = "";
foreach (var word in text.Split('_'))
{
newText += $"{word.ToCamelCase()}_";
}
return newText[..^1];
}
return $"{text.First().ToString().ToLowerInvariant()}{text[1..]}";
}
}
- Add a specific modelBuilder extension to apply this convention to json owned properties :
public static class ModelBuilderExtension
{
public static ModelBuilder ConfigureJsonOwnedPropertiesInCamelCase(this ModelBuilder modelBuilder)
{
foreach (var entityType in modelBuilder.Model.GetEntityTypes()
.Where(entityType => entityType.IsOwned()))
{
foreach (var property in entityType.GetProperties())
{
if (!property.IsPrimaryKey())
{
property.SetJsonPropertyName(property.GetColumnName().ToCamelCase());
}
}
}
return modelBuilder;
}
}
- Call this function in your dbContext file :
public class MyDbContext(DbContextOptions<MyDbContext> options) : DbContext(options)
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Order>().OwnsOne(
order => order.shippingAddress, ownedNavigationBuilder =>
{
ownedNavigationBuilder.ToJson();
ownedNavigationBuilder.OwnsOne(shippingAddress => shippingAddress.Country);
ownedNavigationBuilder.OwnsOne(shippingAddress => shippingAddress.Company);
});
modelBuilder.ConfigureJsonOwnedPropertiesInCamelCase();
}
}
@Rlamotte Indeed, the underlying logic is to use JsonPropertyName
to batch set the properties at each nest elements. The current project already has comprehensive CamelCase-related methods, so the ideal way is to complete these batch settings within the existing project. I will try to see if I can support batch setting the JsonPropertyName
attribute at the lower level.