次のように、Activity のエンティティ モデル集計があるとします。
public class Activity : Entity
{
public int PersonId { get; set; }
public virtual Person Person { get; set; }
public int Number { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public virtual ICollection<ActivityTag> Tags { get; set; }
}
public class ActivityTag : Entity
{
public int ActivityPersonId { get; set; }
public int ActivityNumber { get; set; }
public virtual Activity Activity { get; set; }
public int Number { get; set; }
public string Text { get; set; }
}
Activity と Person の関係は忘れて、Activity と ActivityTag の 1..* 関係に注意してください。流暢なマッピングは多かれ少なかれ次のようになります。
public class ActivityOrm : EntityTypeConfiguration<Activity>
{
public ActivityOrm()
{
ToTable("Activity", "Activities");
HasKey(p => new { p.PersonId, p.Number });
HasRequired(d => d.Person)
.WithMany()
.HasForeignKey(d => d.PersonId)
.WillCascadeOnDelete(true);
HasMany(p => p.Tags)
.WithRequired(d => d.Activity)
.HasForeignKey(d => new { d.ActivityPersonId, d.ActivityNumber })
.WillCascadeOnDelete(true);
Property(p => p.Content).HasColumnType("ntext");
}
}
public class ActivityTagOrm : EntityTypeConfiguration<ActivityTag>
{
public ActivityTagOrm()
{
ToTable("ActivityTag", "Activities");
HasKey(p => new { p.ActivityPersonId, p.ActivityNumber, p.Number });
Property(p => p.Text).IsRequired().HasMaxLength(500);
}
}
Activity
これを踏まえて、エンティティに新しいコレクション プロパティを導入したいと思います。
public ICollection<DraftedTag> DraftedTags { get; set; }
エンティティにはDraftedTag
、 とまったく同じプロパティと主キーが必要ActivityTag
です。異なる必要があるのは、マップ先のテーブルだけです。次のように、ActivityTag から派生したクラスを作成してみました。
public class DraftedTag : ActivityTag
{
}
public class DraftedTagOrm : EntityTypeConfiguration<DraftedTag>
{
public DraftedTagOrm()
{
Map(m =>
{
m.MapInheritedProperties();
m.ToTable("DraftedTag", "Activities");
});
HasKey(p => new { p.ActivityPersonId, p.ActivityNumber, p.Number });
}
}
DraftedTagOrm が modelBuilder.Configurations コレクションに追加されましたが、Activity に外部キーの関連付けを追加しなくても、次の例外が発生します。
プロパティ「ActivityPersonId」は、タイプ「DraftedTag」で宣言されたプロパティではありません。Ignore メソッドまたは NotMappedAttribute データ注釈を使用して、プロパティがモデルから明示的に除外されていないことを確認します。有効なプリミティブ プロパティであることを確認してください。
ActivityTag クラスと ActivityTagOrm コンストラクターのコードをそれぞれの DraftTag クラス / 構成コンストラクターに完全に複製すると、期待どおりに動作します。スキーマは同じですが、名前が異なる 2 つの異なるテーブルが得られます。ただし、ActivityTag クラスに変更を加えるたびに、DraftTag クラスに対応する変更を加える必要があります。
DraftTag に ActivityTag を拡張させることで、このコードを DRYer にすることは可能ですか? もしそうなら、DraftTag の EntityTypeConfiguration はどのようになりますか?