Entity framework 删除所需属性-先删除EF代码
我有一个抽象类,其中需要属性“CreatedBy”。 除了一个实体(UserProfile本身)之外,几乎所有实体都使用了该选项 如何从UserProfile中删除所需的属性,而不从从EntityBase继承的其他实体中删除它Entity framework 删除所需属性-先删除EF代码,entity-framework,model,attributes,data-annotations,Entity Framework,Model,Attributes,Data Annotations,我有一个抽象类,其中需要属性“CreatedBy”。 除了一个实体(UserProfile本身)之外,几乎所有实体都使用了该选项 如何从UserProfile中删除所需的属性,而不从从EntityBase继承的其他实体中删除它 public abstract class EntityBase: IEntityBase { [Key, Column(Order = 0)] public Guid? Id { get; set; } [Key, Column(Order =
public abstract class EntityBase: IEntityBase
{
[Key, Column(Order = 0)]
public Guid? Id { get; set; }
[Key, Column(Order = 1)]
public int Version { get; set; }
[Required]
public DateTime Created { get; set; }
[Required]
public UserProfile CreatedBy { get; set; }
public bool IsDeleted { get; set; }
}
public class UserProfile: EntityBase
{
[Required, Index("Username", 3, IsUnique = true), MaxLength(900)]
public string Username { get; set; }
[Required, Index("Email", 4, IsUnique = true), MaxLength(900)]
public string Email { get; set; }
}
我试图覆盖我的onmodel创建,但那不起作用。。。有人有什么想法吗
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<UserProfile>().HasOptional(profile => profile.CreatedBy).WithMany();
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
基于模型创建(modelBuilder);
modelBuilder.Entity().has可选(profile=>profile.CreatedBy).WithMany();
modelBuilder.Conventions.Remove();
}
奇怪的是,在我的数据库中,UserProfile表中的CreatedBy_Id和CreatedBy_Version列可以为null
当我在UserProfile表中设置种子时,我得到了每个表的一个验证错误,它说:“CreatedBy字段是必需的。”有趣的是,数据库生成逻辑被fluent映射覆盖,但验证逻辑不是。这就是流畅的映射和数据注释之间的紧张关系 我想到的第一件事是:给
UserProfile
类一个例外,不要让它继承自EntityBase
,并给它所需的属性,其中的属性也可以在EntityBase
中找到
但我敢打赌,其他地方的代码依赖于继承基类或实现接口的类
这里的问题是,RequiredAttribute
在其规范中(从其基类,Attribute
)具有Inherited=true
,因此如果您在UserProfile
中重写CreatedBy
,它仍然是必需的
解决方案1-不好
要解决此问题,您可以创建自己的属性,继承RequiredAttribute
,并将其设置为Inherited=false
:
[AttributeUsageAttribute(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter,
AllowMultiple = false,
Inherited = false)]
public class RequiredInBaseClassAttribute : RequiredAttribute
{
}
现在如果你把这个属性放在基类中
[RequiredInBaseClass]
public virtual UserProfile CreatedBy { get; set; }
并在UserProfile中覆盖它
public override UserProfile CreatedBy { get; set; }
在UserProfile
中不再需要它。嗯,是的。EF似乎可以追溯到基本属性上的属性
解决方案2
将Required
属性替换为CustomValidation
属性,当验证类型为UserProfile
时,该属性允许CreatedBy
为空:
public abstract class EntityBase: IEntityBase
{
...
[CustomValidation(typeof(EntityBase), "CreatedByIsValid")]
public UserProfile CreatedBy { get; set; }
public static ValidationResult CreatedByIsValid(UserProfile value, ValidationContext context)
{
return value != null || (context.ObjectInstance is UserProfile)
? ValidationResult.Success
: new ValidationResult("CreatedBy is required");
}
}
所以你实际上设计错了 您的需求显然意味着您不应该继承EntityBase。您不应该试图将此设计强加给您的需求 相反,放松你的整体基础
public abstract class EntityBase: IEntityBase
{
[Key, Column(Order = 0)]
public Guid? Id { get; set; }
[Key, Column(Order = 1)]
public int Version { get; set; }
[Required]
public DateTime Created { get; set; }
public UserProfile CreatedBy { get; set; }
public bool IsDeleted { get; set; }
}
问题解决了
这是正确的方法。实体可以来自任何地方,它们并不总是由用户创建的,因此在设计中提出“所有实体都必须由用户创建”的要求是非常错误的。解释得很好,是一个很好的解决方案!我会马上测试。试过了,但我还是有同样的问题。你知道其他的解决方法吗?我知道的唯一方法。。。是从我的EntityBase中删除required属性,并在OnModelCreating中为从EntityBase派生的其他每个类添加“HasRequired”。但如果有更简单更好的解决方案,我会改变它。因此,建议仍然很受欢迎。EF似乎可以追溯到基本属性上的属性。即使将
CustomValidationAttribute
(始终返回成功)放在覆盖上也不会删除所需的验证。如果我无法访问EntityBase
代码,该怎么办?我的意思是:如果EntityBase
来自一个库,如何解决这个问题?是否有方法删除不需要的属性?如果使用EntityFramework,则可以使用FluentAPI“覆盖”该属性。我必须用我从另一个库中获得的一些属性来实现这一点,我们可以与oracle数据库兼容。FluentAPI优先考虑。仅供参考,只需继承EntityBase并使用new/override重新写入相同的属性,这将擦除属性。