I will show you the code and then explain the problem
public interface IUser
{
Guid ID { get; set; }
string Name { get; set; }
ICollection<IRole> Roles { get; set; }
}
public interface IRole
{
Guid ID { get; set; }
string Name { get; set; }
}
Notice that the interface IUser
define a collection Roles of type IRole
public class Role : IRole
{
public Guid ID { get; set; }
public string Name { get; set; }
}
public class User : IUser
{
public Guid ID { get; set; }
public string Name { get; set; }
public ICollection<IRole> Roles { get; set; }
}
public class RoleConfiguration : EntityTypeConfiguration<Role>
{
public RoleConfiguration()
{
HasKey(p => p.ID)
.Property(p => p.ID);
Property(p => p.Name)
.IsRequired()
.HasMaxLength(70);
}
}
public class UserConfiguration : EntityTypeConfiguration<User>
{
public UserConfiguration()
{
HasKey(p => p.ID)
.Property(p => p.ID)
.IsRequired();
Property(p => p.Name)
.HasMaxLength(60)
.IsRequired();
HasMany(r => r.Roles).WithMany();
}
}
Note that the configuration EntityTypeConfiguration where T is the implementation and not the interface (the EF does not allow to put the interface as T)
#1 situation:
If you run the application, to generate the relational model, the following error occurs:
The navigation property 'Roles' is not a declared property on type 'User'. Verify that it has not been explicitly excluded from the model and that it is a valid navigation property.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: The navigation property 'Roles' is not a declared property on type 'User'. Verify that it has not been explicitly excluded from the model and that it is a valid navigation property.
Source Error:
Line 58: public IQueryable<Project> GetAll(int pageIndex, int pageSize, params Expression<Func<Project, object>>[] includeProperties)
Line 59: {
Line 60: return includeProperties.Aggregate<Expression<Func<Project, object>>,
Line 61: IQueryable<Project>>(Context.Projects, (current, includeProperty) => current.Include(includeProperty)).OrderBy(p => p.Name).Skip(pageIndex).Take(pageSize);
Line 62: }
#2 situation:
If you comment out the line HasMany(r => r.Roles).WithMany();
EF will generate the relational model with no relationship between User
and Role
(which should be many to many)
I believe this is because the User
class, there is a collection type ICollection<IRole>
and not of kind ICollection.
The question is, how to solve this problem?
How to map the collection public ICollection<IRole> Roles { get; set; }
using Fluent API EF
CodeFirst doesn't support mapping interfaces. You will need to change it to reference the Role concrete class.