0

私たちは、適度に大きなアプリケーションをEntity Framework 6.2からEntity Framework Core 2.0に移行しています。多くのことが私が願っていたよりもずっと簡単でしたが、私は、私が最初に(または千分の1)持っていることに疑問を抱く問題にぶつかりましたが、それに対してコンパクトな解決策を見つけることはできません。命名規則。EFコアのEF6の命名規則を再作成

特に、リレーショナルプロパティの命名規則。我々のアプリケーションで

典型的な1対多のエンティティペアは次のようなものになります。当社の既存のデータベースで

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; } 
} 

を、EF6には、次の表にそれをマッピングされた:で

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

をEFコアのデフォルトの命名規則では、移植されたコンテキストでFoo_FooIdの代わりにFooIdという列が検索されるようです。

私はhereの記載内容でこれを修正しようとしましたが、ナビゲーションのプロパティのみを変更するためにプロパティメタデータに課す条件を特定できません。 (私は.Entity<Owner>().OwnsOne(o => o.Owned)で構成する複雑なタイプもいくつか持っているので、解決策もそれをキャプチャする必要があります)

この移行を容易にする既成のソリューションはありませんか?


私はここで、この問題のMVCEを公開した:あなたはシャドウプロパティの名前を変更することはできませんが、テーブルの列の名前を変更することができますhttps://github.com/tlycken/MCVE_EfCoreNavigationalProperties

+0

私が知っている限り、いいえ。 EF Core 1.0に移行したとき、私たちはデータベースを足場にし、それに応じてコードを調整しました。私はこれが何らかの形でより良く変わったことを示唆する投稿を見つけることができません。 – Tubs

答えて

0

私の知る限りを。このように

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; 
      } 
     } 
    } 

} 

もちろん、モデルに外部キープロパティがある場合は、これを行う必要はありません。

+0

ありがとうございます。私はこれで今遊ぶことができましたが、私はそれを働かせることができません、いくつかの理由で:あなたのコードは接頭辞が他のエンティティのテーブル名であると仮定しますが、実際には_this_エンティティのプロパティ名です(たとえば、 'Foo'型のエンティティに' Baz'という名前の 'Bar'型のナビゲーションプロパティがある場合、' Foos'テーブルの列は 'Baz_Bar'でなければなりません)。プロパティの名前を見つける方法を見つけ出す。 –

+0

また、ナビゲーションプロパティに '[ForeignKey(" TheDesiredColumnName ")]'というアノテーションを付けてみました。これは名前を正しく解決するようですが、 'Include'は動作を停止します(すべてのリレーショナルパラメータに対して' null'を返します)。データベースに外部キーがありますが、それは役に立たないようです。 –

+0

また、ここで問題をデモンストレーションする最小限のサンプルアプリケーションをまとめました:https://github.com/tlycken/MCVE_EfCoreNavigationalProperties –