web-dev-qa-db-ja.com

Entity Framework Core 2.0:抽象基本クラスを一度構成する方法

基本モデルがあります:

public abstract class Status
{
     public string updateUserName { get; set; }
}

次に、上記で定義した基本モデルを拡張するモデル:

public class Item : Status
{
     public int Id { get; set; }
     public string Description { get; set; }
}

次に、それぞれに構成クラスを定義しました。

public class ItemConfiguration : IEntityTypeConfiguration<Item>
{
    public void Configure(EntityTypeBuilder<Item> builder)
    {
        builder.ToTable("Item", "dbo").HasKey(c => c.Id);
        builder.Property(c => c.Description).IsRequired().HasMaxLength(100);
    }
}

public class StatusConfiguration : IEntityTypeConfiguration<Status>
{
    public void Configure(EntityTypeBuilder<Status> builder)
    {
        builder.Property(c => c.updateUserName).IsRequired().HasMaxLength(50);
    }

今、私は次のContextクラスを持っています:

public class TestDbContext : DbContext
{
    public TestDbContext(DbContextOptions<TestDbContext> options) : base(options)
    {
    }

    public DbSet<Item> Item { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.ApplyConfiguration(new ItemConfiguration());
    }
}

私は、StatusConfigurationクラスで定義されたStatusモデル構成を、それに拡張するすべてのモデル(この例では1つだけ:Item)に適用する方法を理解しようとしています。使用するたびに同じステータスモデル構成を定義しないようにしたいと思います。ステータスモデルは基本的に、各アイテムレコードに関連付けられたメタデータになります(つまり、両方のモデルで定義されたすべてのプロパティを含むデータベース内の1つのアイテムテーブル。

たとえば、現在の実装は、StatusConfigurationクラスを使用しない次のItemConfigurationクラスです。

public class ItemConfiguration : IEntityTypeConfiguration<Item>
{
    public void Configure(EntityTypeBuilder<Item> builder)
    {
        builder.ToTable("Item", "dbo").HasKey(c => c.Id);
        builder.Property(c => c.Description).IsRequired().HasMaxLength(100);
        builder.Property(c => c.updateUserName).IsRequired().HasMaxLength(50);
    }
}

現在の実装は正しく機能し、意図したとおりにデータベースに移行します。私は単に、今後のより扱いやすい方法を探しています。

私の想定では、ItemConfigurationクラスを拡張してStatusConfigurationクラスを含めることはできますが、そのメソッドの例をオンラインで見つけることができません。もう少し経験がある人が親切に私を正しい方向に向けてくれることを願っていますか?

追加の情報が役立つかどうか教えてください。

11
TheDirtyJenks

私が正しく理解している場合、Statusは単なる基本クラスであり、 データベース継承 に参加している基本entityではありません=。

そのような場合、エンティティモデルと構成内でStatusクラスを直接参照しないことが重要です。つまり、_DbSet<Status>_、タイプStatusまたは_ICollection<Status>_のナビゲーションプロパティがないmodelBuilder.Entity<Status>()呼び出しと_IEntityTypeConfiguration<Status>_なし。

代わりに、常にStatusを継承する具象型を参照する必要があります。設定コードを再利用するには、制約付きジェネリックメソッドまたはクラスを使用し、具象エンティティタイプを渡す必要があります。

IEntityTypeConfigurationクラスを使用しているので、おそらく最も自然なのはStatusConfigurationクラスをジェネリックにすることです。

_public class StatusConfiguration<TEntity> : IEntityTypeConfiguration<TEntity>
    where TEntity : Status
{
    public virtual void Configure(EntityTypeBuilder<TEntity> builder)
    {
        builder.Property(c => c.updateUserName).IsRequired().HasMaxLength(50);
    }
}
_

そして、派生したエンティティ構成クラスがそれから派生するようにします。

_public class ItemConfiguration : StatusConfiguration<Item>
{
    public override void Configure(EntityTypeBuilder<Item> builder)
    {
        base.Configure(builder); // <--
        builder.ToTable("Item", "dbo").HasKey(c => c.Id);
        builder.Property(c => c.Description).IsRequired().HasMaxLength(100);
    }
}
_
30
Ivan Stoev