实体框架6.1.3导航属性仅在查询到相关表

时间:2016-07-01 14:14:10

标签: c# asp.net entity-framework entity-framework-6 asp.net-core-mvc

我有一个ASP.NET 5(dnx46)RC1 我有一个继承自Microsoft.AspNet.Identity(v2.2.1)的IdentityUser类的User类:

在我的DbContext中,我有OnModelCreating:

定义的关系
modelBuilder.Entity<User>()
            .HasMany(u => u.Roles)
            .WithRequired(ur => ur.User)
            .HasForeignKey(ur => ur.UserId);
[Table("Users")]
public class User : BaseUser, IBaseUser
{
// Entity Framework Constructor
private User()
{

}

public User(string userName)
    :base(userName)
{

}
[Key]
public override int Id { get; set; }

public bool IsDeleted { get; set; } = false;

public new virtual ICollection<UserRole> Roles { get; set; } = new List<UserRole>();
}

还有一个角色类:

[Table("Roles")]
public class Role : IdentityRole<int>, IBaseEntity, ISecureEntity
{
    // Entity Framework Constructor
    private Role()
    {

    }
    public Role(string name)
    {
        Name = name;
    }

    public override int Id { get; set; }

    public new string Name { get; set; }

    public new virtual ICollection<UserRole> Users { get; set; }
     public bool IsDeleted { get; set; }
}

连接表的UserRole类:

public class UserRole : IdentityUserRole<int>, IBaseEntity
 {
 // Entity Framework Constructor
 private UserRole()
 {

 }

 public UserRole(int userId, int roleId)
 {
     UserId = userId;
     RoleId = roleId;
 }
 public new int UserId { get; set; }
 public new int RoleId { get; set; }

 public User User { get; set; }
 public Role Role { get; set; }

可以肯定的是,我还在我的DbContext Ctor中明确启用了LazyLoading: Configuration.LazyLoadingEnabled = true; Configuration.ProxyCreationEnabled = true;

我必须这样做:

// HACK: Check if Roles is empty on user too when updating to EF7, else remove these lines
// Lazy loading hack to get the Roles list for currentUser, seems just querying the UsersRoles table fills the roles
var user2 = currentUser;
var userRoles = await _userRoleRepository.GetAsync(r => r.UserId == user2.Id);
/* END HACK */

然后currentUser.Roles导航属性突然拥有所有角色。所以似乎对UsersRoles表的查询以某种方式填充了User类实例的导航属性??

当我对表进行查询时,有人可以解释为什么它可以工作吗?它有什么额外的作用? 更重要的是,如何在没有必要的声明的情况下使导航属性工作?

1 个答案:

答案 0 :(得分:1)

这一点我不久前花了很长时间来追踪它。

不要使用私有构造函数。让它们受到保护。

EF希望创建扩展模型的代理对象并设置导航属性。如果您的默认构造函数是私有的,它不会创建代理,它只会创建一个模型。

另一种解决方法,但我不建议,是对所有查询使用Include语句。如果你说context.Users.Include(x =&gt; x.UserRoles)它会工作。但是,导航属性将停止在包含级别。这可能是一个噩梦,试图保持这一点,并且您将不断编辑您的查询,因为您需要其他导航属性。关于这种方法的一个好处是你保留了私有构造函数而你没有代理对象可能会在其他方面引起一些麻烦。

相关问题