You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Entity Framework将RoomLocation属性映射为指定蛇形命名字段的问题

Solution for Mapping RoomLocation to Prefixed Snake_Case Columns in EF Core + Npgsql

Got it, let's tackle this mapping problem you're having. Since you're already using the SnakeCaseNamingConvention with Npgsql, we just need to ensure the nested RoomLocation properties get prefixed with location_ in your database table. Here are two straightforward ways to do this:

Fluent API gives you full control over the mapping, and works seamlessly with your existing snake case convention. In your DbContext's OnModelCreating method, configure the Room entity to treat RoomLocation as an owned type (a value object that's part of the Room entity, not a separate table):

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    // Keep your existing snake case convention enabled
    modelBuilder.HasPostgresSnakeCaseNamingConvention();

    // Configure the RoomLocation owned type with custom column names
    modelBuilder.Entity<Room>()
        .OwnsOne(room => room.Location, locationBuilder =>
        {
            locationBuilder.Property(loc => loc.Floor).HasColumnName("location_floor");
            locationBuilder.Property(loc => loc.Building).HasColumnName("location_building");
            locationBuilder.Property(loc => loc.Room).HasColumnName("location_room");
        });
}

Why this works:

  • Owned types in EF Core map their properties directly to the parent entity's table (so no separate RoomLocation table is created).
  • We explicitly set each column name to match your desired location_ prefix + snake case property name, which aligns with your existing convention.

2. Using Data Annotations (Simpler for Basic Cases)

If you prefer attribute-based configuration, you can use the [Owned] and [Column] annotations directly on your classes:

First, mark RoomLocation as an owned type (either on the class itself or on the Location property in Room):

public class Room
{
    [Key]
    public Guid Id { get; set; }
    public string Title { get; set; }
    [Owned] // Mark Location as an owned property
    public RoomLocation Location { get; set; }
    public DateTime CreationDate { get; set; }
    public DateTime ModificationDate { get; set; }
}

// Alternatively, mark the RoomLocation class as owned:
// [Owned]
// public class RoomLocation { ... }

Then, add [Column] annotations to each property in RoomLocation to specify the exact column name:

public class RoomLocation
{
    [Column("location_floor")]
    public int Floor { get; set; }
    [Column("location_building")]
    public int Building { get; set; }
    [Column("location_room")]
    public int Room { get; set; }
}

Quick Note on Your Old Project Oddity

Regarding the time you forgot to add builder.HasKey but it still worked with user_-prefixed queries: That's likely because EF Core's default primary key convention kicked in. EF automatically recognizes properties named Id (or <EntityName>Id, like RoomId) as the primary key without explicit configuration. The user_ prefix you saw was probably a side effect of the naming convention applied at the time, but relying on defaults can lead to unexpected behavior later—so sticking with explicit [Key] or fluent configuration is always safer.

内容的提问来源于stack exchange,提问作者Jamal Abo Mokh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 15:47:53