EF 6.1双向映射返回ICollection成员的null结果

时间:2014-05-17 13:41:52

标签: entity-framework entity-framework-6

我有一组允许的角色,以及可以属于多个角色的用户。

我需要查询角色的数量,并从用户实体中知道它属于哪个角色。

第一个查询有效,第二个查询没有(没有返回角色)。

我的代码如下:

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; }
}

对于以下示例,EF创建了3个数据库:

**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

我希望能够运行以下查询:

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!!
}

但是roles.Usersuser.Roles都返回空,但是查看上面的数据库表,它们应该有数据。

我是否需要通过EF Code First明确设置映射,请问我做错了什么?

更新1

我现在正在使用虚拟属性,但仍然返回null:

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!!
}

1 个答案:

答案 0 :(得分:1)

在您的查询中,您需要显式加载相关实体,因为您没有使用延迟加载。

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!!
}

如果您希望延迟加载相关实体,则导航属性必须是虚拟的。