Re-creating naming conventions for EF6 in EF Core

c# entity-framework entity-framework-6 entity-framework-core

Question

We're in the process of migrating our moderately large application from Entity Framework 6.2 to Entity Framework Core 2.0, and while many things have been easier than I had dared to hope for, I've run into a problem that I doubt I'm the first (or the thousandth) one to have, but can't find a compact solution for it: Naming conventions.

Specifically, naming conventions for relational properties.

A typical one-to-many entity pair in our application looks something like this:

public class Foo
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int FooId { get; set; }

    [Required]
    public string Bar { get; set; }

    [InverseProperty(nameof(Baz.Foo))]
    public ICollection<Baz> Bazzes { get; set; }
}

public class Baz
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int BazId { get; set; }

    [Required]
    public string Qux { get; set; }

    [Required]
    public Foo Foo { get; set; }
}

In our existing database, EF6 mapped that to the following tables:

Foos                        Bazzes -- named after the DbSets on the DbContext
****                        ******
FooId : int                 BazId : int
Bar : nvarchar(max)         Qux : nvarchar(max)
                            Foo_FooId : int

With the default naming conventions in EF Core, it seems that the ported context looks for a column FooId instead of Foo_FooId.

I've tried modifying this with something what's described here, but I can't figure out what condition to impose on the property metadata to only change the navigational properties. (I also have a couple of complex type, which I configure with .Entity<Owner>().OwnsOne(o => o.Owned), so the solution needs to capture that as well.)

Is there no ready-made solution to make this transition easier?


I've published an MVCE for this problem here: https://github.com/tlycken/MCVE_EfCoreNavigationalProperties

1
1
12/12/2017 10:53:18 AM

Popular Answer

AFAIK you can't change the name of the Shadow Property, but you can change the name of the table column. Like this

protected override void OnModelCreating(ModelBuilder modelBuilder)
{

    base.OnModelCreating(modelBuilder);

    //modelBuilder.Model.FindEntityType(typeof(Baz)).FindProperty("FooId").Relational().ColumnName = "Foo_FooId";
    foreach( var m in modelBuilder.Model.GetEntityTypes())
    {
        foreach (var sp in m.GetProperties().Where( p => p.IsShadowProperty ))
        {
            var fk = sp.GetContainingForeignKeys().Where(f => f.Properties.Count == 1).FirstOrDefault();
            if (fk != null && fk.PrincipalKey.Properties.Count == 1)
            {
                sp.Relational().ColumnName = fk.PrincipalEntityType.Relational().TableName + "_" + fk.PrincipalKey.Properties.Single().Relational().ColumnName;
            }
        }
    }

}

Of course if you have a Foreign Key Property in your model, you wouldn't have to do this.

1
12/6/2017 6:12:56 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow