Entity Framework Core 2.0:如何配置一次抽象基class
Entity Framework Core 2.0: How to configure abstract base class once
我有一个基础模型:
public abstract class Status
{
public string updateUserName { get; set; }
}
然后是一个扩展上面定义的基本模型的模型:
public class Item : Status
{
public int Id { get; set; }
public string Description { get; set; }
}
然后我为每个定义了配置classes:
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);
}
现在,我有以下上下文class:
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 class 中定义的 Status 模型配置应用到所有扩展到它的模型(本例中只有一个:Item)。我想避免在每次使用时都定义相同的 Status 模型配置。 Status 模型本质上是与每个项目记录关联的元数据(即数据库中的一个项目 table 包含两个模型中定义的所有属性;仅此而已)。
例如,我当前的实现是以下 ItemConfiguration class 而没有使用 StatusConfiguration class:
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 class 以包含 StatusConfiguration class 但无法在线找到该方法的示例。我希望有更多经验的人可以为我指明正确的方向?
如果其他信息有帮助,请告诉我。
如果我没理解错的话,Status
只是一个基地class,并不是实体参与Database Inheritance的基地class。
在这种情况下,切勿直接在实体模型和配置中引用 Status
class,即没有 DbSet<Status>
、Status
类型的导航属性或ICollection<Status>
,没有 modelBuilder.Entity<Status>()
来电,也没有 IEntityTypeConfiguration<Status>
。
相反,您始终必须引用从 Status
继承的具体类型。为了重用配置代码,您应该使用 受约束的泛型 方法或 classes 并传递具体的实体类型。
由于您使用的是 IEntityTypeConfiguration
classes,最自然的方法可能是使您的 StatusConfiguration
class 通用:
public class StatusConfiguration<TEntity> : IEntityTypeConfiguration<TEntity>
where TEntity : Status
{
public virtual void Configure(EntityTypeBuilder<TEntity> builder)
{
builder.Property(c => c.updateUserName).IsRequired().HasMaxLength(50);
}
}
并让派生实体配置 classes 从中派生:
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);
}
}
我有一个基础模型:
public abstract class Status
{
public string updateUserName { get; set; }
}
然后是一个扩展上面定义的基本模型的模型:
public class Item : Status
{
public int Id { get; set; }
public string Description { get; set; }
}
然后我为每个定义了配置classes:
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);
}
现在,我有以下上下文class:
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 class 中定义的 Status 模型配置应用到所有扩展到它的模型(本例中只有一个:Item)。我想避免在每次使用时都定义相同的 Status 模型配置。 Status 模型本质上是与每个项目记录关联的元数据(即数据库中的一个项目 table 包含两个模型中定义的所有属性;仅此而已)。
例如,我当前的实现是以下 ItemConfiguration class 而没有使用 StatusConfiguration class:
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 class 以包含 StatusConfiguration class 但无法在线找到该方法的示例。我希望有更多经验的人可以为我指明正确的方向?
如果其他信息有帮助,请告诉我。
如果我没理解错的话,Status
只是一个基地class,并不是实体参与Database Inheritance的基地class。
在这种情况下,切勿直接在实体模型和配置中引用 Status
class,即没有 DbSet<Status>
、Status
类型的导航属性或ICollection<Status>
,没有 modelBuilder.Entity<Status>()
来电,也没有 IEntityTypeConfiguration<Status>
。
相反,您始终必须引用从 Status
继承的具体类型。为了重用配置代码,您应该使用 受约束的泛型 方法或 classes 并传递具体的实体类型。
由于您使用的是 IEntityTypeConfiguration
classes,最自然的方法可能是使您的 StatusConfiguration
class 通用:
public class StatusConfiguration<TEntity> : IEntityTypeConfiguration<TEntity>
where TEntity : Status
{
public virtual void Configure(EntityTypeBuilder<TEntity> builder)
{
builder.Property(c => c.updateUserName).IsRequired().HasMaxLength(50);
}
}
并让派生实体配置 classes 从中派生:
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);
}
}