如何覆盖基础 类 字段功能?
How do I override base classes field functionality?
嗯,我有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; }
}
派生自 BaseModel
在 BaseModel
中,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; }
}
Id
in Update
将覆盖 Id
in BaseModel
好吧,您可以在 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);
}
}
您可以使用以下技术(在 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; }
}
在您的上下文 class(继承自 DbContext
)中,您可以通过覆盖 OnModelCreating
方法来覆盖 Update
实体的设置:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Update>()
.Property(x => x.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
引用自this reference:
You can further configure your model by using data annotations or the fluent API. Precedence is given to configuration through the fluent API followed by data annotations and then conventions.
这意味着您可以使用流畅的 API(通过 OnModelCreating
)覆盖数据注释配置。
嗯,我有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; }
}
派生自 BaseModel
在 BaseModel
中,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; }
}
Id
in Update
将覆盖 Id
in BaseModel
好吧,您可以在
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);
}
}
您可以使用以下技术(在 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; }
}
在您的上下文 class(继承自 DbContext
)中,您可以通过覆盖 OnModelCreating
方法来覆盖 Update
实体的设置:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Update>()
.Property(x => x.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
引用自this reference:
You can further configure your model by using data annotations or the fluent API. Precedence is given to configuration through the fluent API followed by data annotations and then conventions.
这意味着您可以使用流畅的 API(通过 OnModelCreating
)覆盖数据注释配置。