实体框架属性隐藏

本文关键字:隐藏 属性 框架 实体 | 更新日期: 2023-09-27 18:11:03

我正在使用实体框架6.0.2 Code First with Sql Server。

我有一个名为Entity的基类,因为我们不能扩展枚举,所以我需要为另一个名为Company的类重新定义属性类型,所以我使用new关键字来隐藏基属性并重新定义它。

public interface IEntity 
{
    Guid Id { get; set; }
    State State { get; set; }
}
public abstract class Entity : IEntity
{
   public Guid Id { get; set; }
   public State State { get; set; }
}
public enum State 
{
   Inactive = 0,
   Active = 1
}
public class Company : Entity 
{
   public new CompanyState State { get; set; }
   public string SomeOtherProp { get; set; }
}
public enum CompanyState 
{
   Inactive = 0,
   Active = 1,
   Extra = 2
}

我得到的问题是,当实体框架试图创建DbContext时,它崩溃了这个错误:"具有身份'状态'的项目已经存在于元数据集合中。参数名称:item"

我有一个解决方法:我可以将Entity类中的State属性更改为int并将适当的enum强制转换为int,但我认为我会失去枚举所具有的类型安全/限制。

我想更改元数据信息以避免此错误,但我不知道如何。

实体框架属性隐藏

这个家伙找到了一个类似问题的解决方案。

你的解决方案和他的解决方案都不好。它是而且仍然是一个黑客。我同意你已经提到的解决方案。将state修改为stateId。并为Entity添加State Property:
public State State {get {return (State)stateId;}

在你的公司用new:

覆盖此属性
public new CompanyState State {get {return (CompanyState )stateId;}

但我认为最好的解决方案将是,改变你的继承层次。我认为要么你的IEntity不应该有状态,要么你的公司不应该从Entity继承。

只是为了暴露另一种方式,您还可以将此模型与隐藏的后台字段和未映射的状态一起使用

public interface IEntity
{
    int Id { get; set; }
    State State { get; set; }
}
public abstract class Entity : IEntity
{
    protected int InternalState { get; set; }
    public int Id { get; set; }
    [NotMapped]
    public State State
    {
        get { return (State) InternalState; }
        set { InternalState = (int) value; }
    }
    // Entity is not a POCO class because of this :(
    // If we want to hide InternalState this is the only way to map it
    public class EntityMap : EntityTypeConfiguration<Entity>
    {
        public EntityMap()
        {
            // Properties
            Property(t => t.InternalState)
                .HasColumnName("State");
        }
    }
}
public enum State
{
    Inactive = 0,
    Active = 1
}
public class Company : Entity
{
    [NotMapped]
    public new CompanyState State
    {
        get { return (CompanyState)InternalState; }
        set { InternalState = (int)value; }
    }
    [MaxLength(50)]
    public string SomeOtherProp { get; set; }
}
public class Employee : Entity
{
    [MaxLength(50)]
    public string SomeOtherProp { get; set; }
}
public enum CompanyState
{
    Inactive = 0,
    Active = 1,
    Extra = 2
}