【问题标题】:Ef core many to many relationship inside a generic repository通用存储库中的 Ef 核心多对多关系
【发布时间】:2018-10-31 22:31:55
【问题描述】:

我正在尝试在我的 Web 应用程序中处理多对多关系。我正在使用通用存储库基本代码。

这是我的实体

public class UserEntity : BaseEntity<int>
{
    public string EmployeeId { get; set; }
    public string FullName { get; set; }
    public string Email { get; set; }

    public virtual ICollection<UserRoleEntity> UserRoles { get; set; }
}

public class RoleEntity : BaseEntity<int>
{
    public string Name { get; set; }

    public virtual ICollection<UserRoleEntity> Users { get; set; }
}

public class UserRoleEntity : BaseEntity<Guid>
{
    public int UserId { get; set; }
    public int RoleId { get; set; }

    public virtual UserEntity UserEntity { get; set; }
    public virtual RoleEntity RoleEntity { get; set; }
}

这是上下文模型配置

private void ConfigureUserRole(EntityTypeBuilder<UserRoleEntity> builder)
{
    builder.ToTable("UserRole");

    //there is no need for a surrogate key on many-to-many mapping table
    builder.Ignore("Id");

    builder.HasKey(ur => new { ur.RoleId, ur.UserId });

    builder.HasOne(ur => ur.RoleEntity)
        .WithMany(r => r.Users)
        .HasForeignKey(ur => ur.RoleId);

    builder.HasOne(ur => ur.UserEntity)
        .WithMany(u => u.UserRoles)
        .HasForeignKey(ur => ur.UserId);
}

这是我的通用存储库的主要get方法(实际上是Chris Prattimplementation)请注意query.Include这一行,通用存储库的get方法使用EF Core的Include api获取作为字符串参数的依赖实体。

 protected virtual IQueryable<T> GetQueryable(Expression<Func<T, bool>> filter = null, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null,
                                                    string includeProperties = null,
                                                    int? skip = null,
                                                    int? take = null)
        {
            includeProperties = includeProperties ?? string.Empty;
            IQueryable<T> query = _dbContext.Set<T>();

            if (filter != null)
            {
                query = query.Where(filter);
            }

            foreach (var includeProperty in includeProperties.Split
                (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
            {
                query = query.Include(includeProperty);
            }

            if (orderBy != null)
            {
                query = orderBy(query);
            }

            if (skip.HasValue)
            {
                query = query.Skip(skip.Value);
            }

            if (take.HasValue)
            {
                query = query.Take(take.Value);
            }

            return query;
        }

在我的服务中,我想获取用户数据及其全部依赖项。

public class UserService : IUserService
{
    private IRepository<UserEntity> _userRepository;
    private IRepository<RoleEntity> _roleRepository;

    public UserService(IRepository<UserEntity> userRepository, IRepository<RoleEntity> roleRepository)
    {
        _userRepository = userRepository;
        _roleRepository = roleRepository;
    }
    public UserEntity GetUserData(string employeeId)
    {
        var user = _userRepository.GetFirst(u => u.EmployeeId == employeeId, includeProperties: "UserRoles");
        //var roles = _roleRepository.GetAll().ToList();

        return user;
    }
}

当执行上述服务代码时,我得到了具有UserRole 依赖的用户,但是,当我检查我需要的UserRoleRoleEntity 依赖时,它是null

  • 如何仅通过修改通用存储库的 get 方法来获取依赖的 RoleEntity 数据?

  • 其次,在服务代码中注释的行(_roleRepository.GetAll()),当它也被执行时,RoleEntity 会立即填充其正确的值。情况如何?

【问题讨论】:

    标签: c# entity-framework-core


    【解决方案1】:

    您的包含路径只有一个从 UserEntityUserRoleEntity 的跃点(通过 UserRoles 属性。您需要包含下一步以确保您还捕获了 RoleEntity。为此,请更改您的UserRoles.RoleEntity 的路径,例如:

    var user = _userRepository.GetFirst(
        u => u.EmployeeId == employeeId, 
        includeProperties: "UserRoles.RoleEntity");
    

    【讨论】:

    • 谢谢@DavidG,我无法想象它会这么容易,文档对此一无所知。对于我的第二个问题,你知道这是怎么发生的吗?
    • 您的对象层次结构是 User -> UserRole -> Role 并且您只加载了中间部分。如果您使用的是 Include 方法的 lambda 版本,那可能会更清楚一些。
    • 是的,我知道了,但我问的是,当我通过其单独的存储库从 db 调用角色数据时,User.UserRole.RoleEntity 是如何填充的?在该行之前RoleEntity 为空,但在执行该行之后,我检查RoleEntity,它似乎已被填充。
    • 我想我已经从this的提示中得到了我第二个问题的答案@
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-15
    • 2017-02-08
    • 2018-05-27
    • 1970-01-01
    相关资源
    最近更新 更多