Reputation: 33
I'm working with Entity Framework 6.0.2 Code First with Sql Server.
I have a base class called Entity and since we can't extend enums I need to redefine a property type for another class called Company, so I'm using the new keyword to hide the base property and redefine it.
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
}
The problem I get is when Entity Framework is trying to create the DbContext it crashes with this error: "The item with identity 'State' already exists in the metadata collection. Parameter name: item"
I have a workaround: I could change the State propery in Entity class to int and cast the appropriate enum to int, but I think I'll lose type safety / restriction that the enums have.
I'd like to change the metadata info to avoid this error but I don't know how.
Upvotes: 3
Views: 4890
Reputation: 6501
Just for exposing another way you could also use this model with an hidden backing field and not mapped states
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
}
Upvotes: 0
Reputation: 3382
This guy here found a solution for some similar problem.
Neither your, nor his solution is nice. It is and remains a hack.
I would go with the solution you already mentioned. Change the state
to stateId
. And add a State Property to your Entity
:
public State State {get {return (State)stateId;}
In your Company override this Property with new:
public new CompanyState State {get {return (CompanyState )stateId;}
But I think best solution would be, to change your inheritance hierarchy. I think either your IEntity should not have a state, or your company should not inherit from Entity.
Upvotes: 1