Reputation: 22652
I have referred many stack overflow questions like EntityType 'MyProfile' has no key defined. Define the key for this EntityType. And the solution mentioned is to define [Key]
Attribute.
I am getting the following error even after adding the [Key] attribute (when I try to insert an employee). How can we resolve this?
EntityType 'Role' has no key defined. Define the key for this EntityType.
Note: I am getting the same error even after adding a setter for RoleID.
public abstract int RoleID { get; set; }
Note: The Role class is abstract
class
EF Code First
public static void InsertEmployees()
{
string connectionstring = @"Data Source=.;Initial Catalog=My19June_A;Integrated Security=True;Connect Timeout=30";
using (var db = new My19June_A(connectionstring))
{
Employee emp1= new Employee();
emp1.EmployeeID = 1;
emp1.IsActiveEmployee = true;
Employee emp2 = new Employee();
emp2.EmployeeID = 2;
emp2.IsActiveEmployee = true;
db.Employees.Add(emp1);
db.Employees.Add(emp2);
int recordsAffected = db.SaveChanges();
}
}
Entities
public abstract class Role : IEntityWithKey
{
public EntityKey EntityKey { get; set; }
public abstract string RoleName { get; }
[Key]
public abstract int RoleID { get; }
}
public class ProgrammerRole : Role, IEntityWithKey
{
public EntityKey EntityKey { get; set; }
public override string RoleName { get { return "Programmer"; } }
[Key]
public override int RoleID { get { return 101; } }
}
public class ManagerRole : Role, IEntityWithKey
{
public EntityKey EntityKey { get; set; }
public override string RoleName { get { return "Manager"; } }
[Key]
public override int RoleID { get { return 102; } }
}
public class Employee : IEntityWithKey
{
public EntityKey EntityKey { get; set; }
private bool isActiveEmployee;
private IList<Role> roles;
public virtual IList<Role> RolesList
{
get
{
return roles;
}
}
public bool IsActiveEmployee
{
get
{
return isActiveEmployee;
}
set
{
isActiveEmployee = value;
}
}
public int EmployeeID { get; set; }
//Constructor
public Employee()
{
roles = new List<Role>();
}
public void TerminateEmployeeByRole(Role role)
{
if (RolesList == null)
{
//If employee has no role, make as inactive
isActiveEmployee = false;
}
else
{
//If employee has no role other than the input role, make as inactive
RolesList.Remove(role);
if (RolesList.Count == 0)
{
isActiveEmployee = false;
}
}
}
}
Upvotes: 0
Views: 1674
Reputation: 1475
Unless I'm greener at this then I think, you should read up on how the Code First way of using Entity Framework works. :)
The following is how I would create something like what you are trying to do, I haven't actually built the code so there might be errors:
public class Role
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)] // since you set the IDs in code
public int RoleID { get; set; }
public string RoleName { get; set; }
}
public class Employee
{
public int EmployeeID { get; set; }
public ICollection<Role> Roles { get; set; } // make it virtual for lazy loading
}
And in My19June_A:
public class My19June_A : DbContext
{
public DbSet<Employee> { get; set; }
public DbSet<Role> { get; set; }
static My19June_A()
{
Database.SetInitializer<RegistryContext>(new CreateInitializer());
}
class CreateInitializer : CreateDatabaseIfNotExists<RegistryContext>
{
protected override void Seed(RegistryContext context)
{
void Seed()
{
var programmerRole = new Role() { RoleID = 101, RoleName = "Programmer" };
var managerRole = new Role() { RoleID = 102, RoleName = "Manager" };
context.Roles.Add(programmerRole);
context.Roles.Add(managerRole);
context.SaveChanges();
}
}
}
}
You can get the roles by selecting on their respective Id. However another possibility is to completely skip storing the roles in the database since you seem to want specific classes for the different roles. A role in the database can then be stored with a just an int-value.
Upvotes: 1