好吧,我有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
中的 Update
会覆盖Id
中的BaseModel
答案 0 :(得分:3)
您可以使用以下技术(在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; }
}
答案 1 :(得分:1)
您可以隐藏
BaseModel
UpdateModel
中的ID
public class UpdateModel : BaseModel
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public new int Id { get; set; }
public DateTime Updated { get; set; }
}
根据评论,上述解决方案从程序化的角度来看是完全错误的,因为如果您将从Id
派生的任何实体投射到UpdateModel
,则支持字段BaseModel
将为空它将编译并给出所需的结果。
检查以下解决方案
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);
}
}
答案 2 :(得分:1)
在您的上下文类(继承自DbContext
)中,您可以通过覆盖Update
方法来覆盖OnModelCreating
实体的设置:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Update>()
.Property(x => x.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
您可以使用数据注释或流畅的API进一步配置模型。优先通过流畅的API进行配置,然后是数据注释,然后是约定。
这意味着您可以使用流畅的API覆盖数据注释配置(通过OnModelCreating
)。