如何重写基类字段功能

本文关键字:基类 字段 功能 重写 何重写 | 更新日期: 2023-09-27 18:21:44

好吧,我有BaseModel

public class BaseModel
{
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }
    public bool Deleted { get; set; }
}

我也有模型Update

public class Update : BaseModel
{
    public DateTime Updated { get; set; }
}

它源自BaseModelBaseModel Id字段中没有递增,但对于Update模型,我需要Id Identity.

我可以向Update添加新字段,例如UpdateId,这将递增,但删除字段Id


有没有可能的解决方案?

如何以另一种方式声明模型

public class BaseModel
{
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }
    public bool Deleted { get; set; }
}

public class Update : BaseModel
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public DateTime Updated { get; set; }
}

Update 中的Id将覆盖BaseModel中的Id

如何重写基类字段功能

可以使用以下技术(在 Windows 窗体控件中大量使用,以将不同的属性应用于同一属性(:

public class BaseModel
{
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public virtual int Id { get; set; }
    public bool Deleted { get; set; }
}
public class Update : BaseModel
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public override int Id { get { return base.Id; } set { base.Id = value; } }
    public DateTime Updated { get; set; }
}

在上下文类(继承自 DbContext (中,可以通过重写 OnModelCreating 方法重写Update实体的设置,如下所示:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    modelBuilder.Entity<Update>()
        .Property(x => x.Id)
        .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}

引用此参考资料:

您可以使用数据注释或流畅的 API 进一步配置模型。通过流畅的 API 为配置提供优先级,然后是数据注释,然后是约定。

这意味着您可以使用流畅的 API 覆盖数据注释配置(通过 OnModelCreating (。

好吧,您可以在UpdateModel中隐藏BaseModel的 ID public class UpdateModel : BaseModel { [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public new int Id { get; set; } public DateTime Updated { get; set; } }

编辑

根据注释,从编程的角度来看,上述解决方案是完全错误的,因为如果您将从UpdateModel派生的任何实体转换为BaseModel,则支持字段Id将为空,尽管它将编译并给出所需的结果。

检查以下解决方案

public class BaseEntity
{
    public int Id { get; set; }
    public bool Deleted { get; set; }
}
public class UpdateEntity : BaseEntity
{
    public DateTime Updated { get; set; }
}
public class Entity1 : BaseEntity
{
    public string Name { get; set; }
}
public class Entity2 : UpdateEntity
{
    public string Name { get; set; }
}
public abstract class BaseEntityTypeConfiguration<T> : EntityTypeConfiguration<T>
    where T : BaseEntity
{
    public BaseEntityTypeConfiguration()
    {
        Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
    }
}
public abstract class UpdateEntityTypeConfiguration<T> : EntityTypeConfiguration<T>
    where T : UpdateEntity
{
    public UpdateEntityTypeConfiguration()
    {
        Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    }
}
public class Entity1Configuration : BaseEntityTypeConfiguration<Entity1>
{
    public Entity1Configuration()
        : base()
    {
        Property(x => x.Name).HasMaxLength(100);
    }
}
public class Entity2Configuration : UpdateEntityTypeConfiguration<Entity2>
{
    public Entity2Configuration()
        : base()
    {
        Property(x => x.Name).HasMaxLength(100);
    }
}
public class MyDbContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        var typesToRegister = from type in Assembly.GetExecutingAssembly().GetTypes()
                              where !string.IsNullOrEmpty(type.Namespace) &&
                                    type.BaseType != null &&
                                    type.BaseType.IsGenericType
                              let genericType = type.BaseType.GetGenericTypeDefinition()
                              where genericType == typeof(BaseEntityTypeConfiguration<>) || genericType == typeof(UpdateEntityTypeConfiguration<>)
                              let genericArgument = type.BaseType.GetGenericArguments().FirstOrDefault()
                              where genericArgument != null && genericArgument.BaseType != null &&
                              (genericArgument.BaseType == typeof(BaseEntity) || genericArgument.BaseType == typeof(UpdateEntity))
                              select type;
        foreach (var type in typesToRegister)
        {
            dynamic configurationInstance = Activator.CreateInstance(type);
            modelBuilder.Configurations.Add(configurationInstance);
        }
        base.OnModelCreating(modelBuilder);
    }
}