实体框架属性隐藏

时间:2015-09-02 15:37:57

标签: c# entity-framework enums

我正在使用Sql Server实现Entity Framework 6.0.2 Code First。

我有一个名为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
}

我得到的问题是当Entity Framework尝试创建DbContext时它会因此错误而崩溃:“元数据集合中已存在具有标识'State'的项目。参数名称:item”

我有一个解决方法:我可以将Entity类中的State propery更改为int并将相应的枚举转换为int,但我认为我将丢失枚举所具有的类型安全/限制。

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

2 个答案:

答案 0 :(得分:1)

This guy here找到了解决某些类似问题的方法。

你和他的解决方案都不好。它现在仍然是一个黑客。 我会选择你已经提到的解决方案。将state更改为stateId。并为您的Entity添加州财产:

public State State {get {return (State)stateId;}

在贵公司中,使用new:

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

但我认为最好的解决方案会改变您的继承层次结构。我认为您的IEntity不应该有州,或者您的公司不应该从实体继承。

答案 1 :(得分:0)

只是为了暴露另一种方式,您也可以将此模型与隐藏的支持字段一起使用,而不是映射状态

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
}