Reputation: 2431
I have a set of allowed Roles, and Users who can belong to a number of Roles.
I need to query both the number of Roles, and know from within the User entity to which Roles it belongs.
The first query works, the second query does not (no Roles are returned).
My code is below:
class User
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
[Index(IsUnique=true)]
public string Username { get; set; }
public ICollection<Role> Roles { get; set; }
public User()
{
this.Roles = new List<Role>();
}
}
class Role
{
[Key]
public int Id { get; set; }
[Index(IsUnique = true)]
public string Name { get; set; }
public ICollection<User> Users { get; set; }
}
class MemberContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
}
For the below example EF has created 3 databases:
**Roles {Id,Name}**
1, IdentityServerUsers
2, IdentityServerAdministrators
**UserRoles {User_Id,Role_Id}**
5179EF31-C7DD-E311-80BD-00155D458501, 2
**Users {Id,Name}**
5179EF31-C7DD-E311-80BD-00155D458501, admin
I want to be able to run the following queries:
using(var context = new MemberContext())
{
var roles = context.Roles.Where(x => x.Name == "IdentityServerAdministrators").FirstOrDefault();
// roles.Users is empty!!!
var user = context.Users.Where(x => x.Username == "admin").FirstOrDefault();
// user.Roles is empty!!
}
But the roles.Users
and user.Roles
both return empty, but looking at the above database tables they should have data.
Do I need to explicitly set mapping via EF Code First and what am I doing wrong please?
Update 1
I am now using virtual properties, but still null's are being returned:
class Role
{
[Key]
public int Id { get; set; }
[MaxLength(127)]
[Index(IsUnique = true)]
public string Name { get; set; }
public virtual ICollection<User> Users { get; set; }
}
class User
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
[Index(IsUnique = true)]
[MaxLength(127)]
public string Name { get; set; }
}
using (var context = new MemberContext())
{
var unf1 = context.Roles.Where(x => x.Name == "IdentityServerAdministrators").FirstOrDefault();
var wow1 = unf1.Users;
// roles.Users is empty!!!
var unf2 = context.Users.Where(x => x.Username == "admin").FirstOrDefault();
var wow2 = unf2.Roles;
// user.Roles is empty!!
}
Upvotes: 0
Views: 132
Reputation: 574
In your queries, you need to explicitly load the related entities since you're not using lazy loading.
using(var context = new MemberContext())
{
var roles = context.Roles.Include(x => x.Users).Where(x => x.Name == "IdentityServerAdministrators").FirstOrDefault();
// roles.Users is empty!!!
var user = context.Users.Include(x => x.Roles).Where(x => x.Username == "admin").FirstOrDefault();
// user.Roles is empty!!
}
If you want the related entities to be lazy loaded, the navigation properties must be virtual.
Upvotes: 1