简体   繁体   中英

Entity Framework Core 2 Owned Entity Types - Change Names of Table Columns

I have entity classes, something like this:

public class Bike
{
    public int Id { get; set; }

    public int ModelId { get; set; }

    public Model Model { get; set; }

    public Contact Contact { get; set; }
}

[Owned]
public class Contact
{
    [Required]
    [StringLength(255)]
    public string Name { get; set; }

    [StringLength(255)]
    public string Email { get; set; }

    [Required]
    [StringLength(255)]
    public string Phone { get; set; }
}

It will generate table by default:

 migrationBuilder.CreateTable(
            name: "Bike",
            columns: table => new
            {
                Id = table.Column<int>(nullable: false)
                    .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
                ModelId = table.Column<int>(nullable: false),
                Contact_Name = table.Column<string>(maxLength: 255, nullable: false),
                Contact_Email = table.Column<string>(maxLength: 255, nullable: true),
                Contact_Phone = table.Column<string>(maxLength: 255, nullable: false)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_Bike", x => x.Id);
                table.ForeignKey(
                    name: "FK_Bike_Models_ModelId",
                    column: x => x.ModelId,
                    principalTable: "Models",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.Cascade);
            });

As you can see column names are: Contact_Name, Contact_Email, Contact_Phone .
How to get rid of "_" to get ContactName ... ?

Name the columns explicitly:

modelBuilder.Entity<Order>().OwnsOne(
    o => o.ShippingAddress,
    sa =>
    {
        sa.Property(p => p.Street).HasColumnName("ShipsToStreet");
        sa.Property(p => p.City).HasColumnName("ShipsToCity");
    });

https://docs.microsoft.com/en-us/ef/core/modeling/owned-entities

Another more complex example (nested owned entity) look this

            empleador.OwnsOne(
            property => property.RepresentanteLegal,
            configuration =>
            {
                configuration.Property(repLegal => repLegal.Nombre).HasColumnName("Nombre").HasMaxLength(500);
                configuration.OwnsOne(
                    property => property.Rut,
                    rutConfiguracion =>
                    {
                        rutConfiguracion.Property(rut => rut.DigitoVerificador).HasColumnName("RepLegalRutDv");
                        rutConfiguracion.Property(rut => rut.Numero).HasColumnName("RepLegalRutNumero");
                    });
            });

You can override the OnModelCreating method of your DbContext to avoid naming every column names explicitly.

The following example will remove the underscores from the column names:

public class MyDbContext : DbContext
{    
    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        foreach(var entity in builder.Model.GetEntityTypes())
        {           
            foreach(var property in entity.GetProperties())
            {
                property.Relational().ColumnName = property.Relational().ColumnName.Replace("_", String.Empty);
            }
        }
    }
}

spidyx answer won't work in the case of Owned types, because their definition sits in navigations.

But anywho, I was trying to find a way to do it in a more "reflection fashion way" after OwnsOne's are already set in ModelBuilder, here is a snippet:

private void SetupNamesConvention(ModelBuilder modelBuilder)
{   
    foreach (var entityType in modelBuilder.Model.GetEntityTypes())
    {
        foreach (var navigation in entityType.GetNavigations().Where(x => x.ClrType == typeof(YOUR_OWNS_ONE_PROPERTY)))
        {
            foreach (var fkProperty in navigation.ForeignKey.DeclaringEntityType.GetProperties())
            {
                // your code to set naming conventions
                ...
                fkProperty.Relational().ColumnName;
                ...
            }
        }
    }
}

It may be useful if doing it through:

.OwnsOne(e => e.Address, cb => { cb.Property(e => e.Postcode).HasColumnName("Postcode"); });

Is not optimal,like you have some custom logic that goes through every property and sets naming conventions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM