Context
My application is using a PostgreSQL database with a specific naming convention in camelCase.
Using EF Core 8.0.1, I'm trying to use a Jsonb column with a different naming convention in C# (PascalCase)
Each other table names, properties, primary keys and foreign keys are updated on a specific OnModelCreating function which converts each value to camelCase.
Example
I have an OrderEntity which is currently composed by several properties :
[Index(nameof(Reference), IsUnique = true)]
public class OrderEntity : BaseEntity
{
public Guid Id { get; set; }
public required string Reference { get; set; }
public Guid OrganizationId { get; set; }
//Other properties here...
public required OrderAddress ShippingAddress { get; set; }
public OrganizationEntity Organization { get; set; } = null!;
}
ShippingAddress is a jsonb column in PostgreSQL, with the following properties inside :
public class OrderAddress
{
public string? FirstName { get; set; }
public string? LastName { get; set; }
public string? Street { get; set; }
public string? ZipCode { get; set; }
public string? City { get; set; }
public OrderAddressCountry? Country { get; set; }
public OrderAddressCompany? Company { get; set; }
}
Configuration of ShippingAddress is made using FluentAPI in my dbContext file :
public class OrderManagementDbContext(DbContextOptions<OrderManagementDbContext> options) : DbContext(options)
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<orderEntity>().OwnsOne(
order => order.ShippingAddress, ownedNavigationBuilder =>
{
ownedNavigationBuilder.ToJson();
ownedNavigationBuilder.OwnsOne(shippingAddress => shippingAddress.Country);
ownedNavigationBuilder.OwnsOne(shippingAddress => shippingAddress.Company);
});
modelBuilder.ConfigureCamelCase();
}
//Tables
public virtual DbSet<OrderEntity> Orders { get; set; }
}
Result
When executing requests against orderEntity, I get the following error :
Npgsql.PostgresException (0x80004005): 42703: column p.ShippingAddress does not exist
When I create a migration, my table reflects this naming convention issue :
migrationBuilder.CreateTable(
name: "order",
columns: table => new
{
id = table.Column<Guid>(type: "uuid", nullable: false),
reference = table.Column<string>(type: "text", nullable: false),
organizationId = table.Column<Guid>(type: "uuid", nullable: false),
ShippingAddress = table.Column<string>(type: "jsonb", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("order_pkey", x => x.id);
table.ForeignKey(
name: "order_organization_organizationId_fkey",
column: x => x.organizationId,
principalTable: "organization",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
});
I already tried these methods without success:
Globally update
JsonSerializerOptions.PropertyNamingPolicytoJsonNamingPolicy.CamelCaseGlobally set
JsonSerializerOptions.PropertyNameCaseInsensitiveto falseSet
ShippingAddressname with column data annotationSet
ShippingAddressname with Fluent APIHasColumnNamefunctionSet
ShippingAddressname inOwnsOnefunction withToTableandExcludeFromMigrationsfunctionsManually set navigation name in camel case using
modelBuilder.Model.GetEntityTypes().GetDeclaredNavigations()and then check forIsOwned()targetEntityType and then useSetFieldfunction :foreach (var navigationProperty in tableConfiguration.GetDeclaredNavigations()) { if (navigationProperty.TargetEntityType.IsOwned()) { navigationProperty.SetField(navigationProperty.Name.ToCamelCase()); } }But I get another error while running the mutation:
Unable to create a 'DbContext' of type ''. The exception 'The specified field 'shippingAddress' could not be found for property 'OrderEntity.ShippingAddress'.' was thrown while attempting to create an instance. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
Same tests than 6. with "GetNavigations()" instead of "GetDeclaredNavigations"
Thanks for your help !
Solved with the following choices :