如何渴望在NHibernate中加载实体的所有集合

问题描述 投票:0回答:1

我有这个模特:

public class Group
{
    protected Group()
    {
    }

    public Group(string name)
    {
    }

    public virtual Guid Id { get; set; }
    public virtual string Name { get; set; } = string.Empty;
    public virtual IList<User> Members { get; set; } = new List<User>();
    public virtual IList<Claim> Permissions { get; set; } = new List<Claim>();
}

public class User
{
    protected User()
    {

    }

    public User(string id, string userName, string fullName, IList<Group> groups)
    {
        Id = id;
        UserName = userName;
        FullName = fullName;
        Groups = groups;
    }

    public virtual string Id { get; set; } = string.Empty;
    public virtual string UserName { get; set; } = string.Empty;
    public virtual string FullName { get; } = string.Empty;
    public virtual bool IsEnabled { get; set; } = true;

    public virtual IList<Group> Groups { get; set; } = new List<Group>();
    public virtual IList<Claim> Permissions { get; set; } = new List<Claim>();
}

public class Claim
{
    public virtual Guid Id { get; set; } = Guid.Empty;
    public virtual string ClaimType { get; set; } = string.Empty;
}

和此映射:

public class UserMappings : ClassMap<User>
{
    public UserMappings()
    {
        Table("Users");
        Cache.ReadWrite();
        Id(x => x.Id).GeneratedBy.Assigned();
        Map(x => x.UserName).Not.Nullable();
        Map(x => x.FullName).Not.Nullable();
        HasManyToMany(x => x.Groups)
            .Table("GroupMembers")
            .ParentKeyColumn("UserId")
            .ChildKeyColumn("GroupId")
            .Cascade.SaveUpdate()
            .Cache.ReadWrite();

        HasManyToMany(x => x.Permissions)
            .Table("UserPermissions")
            .ParentKeyColumn("UserId")
            .ChildKeyColumn("ClaimId")
            .Cascade.SaveUpdate()
            .Cache.ReadWrite();

    }
}

public class ClaimMappings : ClassMap<Claim>
{
    public ClaimMappings()
    {
        Table("Claims");
        Cache.ReadWrite();
        Id(x => x.Id).GeneratedBy.GuidComb();
        Map(x => x.ClaimType).Not.Nullable();
    }
}

public class GroupMappings : ClassMap<Group>
{
    public GroupMappings()
    {
        Table("Groups");
        Cache.ReadWrite();
        Id(x => x.Id).GeneratedBy.GuidComb();
        Map(x => x.Name).Not.Nullable();
        HasManyToMany(x => x.Members)
            .Table("GroupMembers")
            .ParentKeyColumn("GroupId")
            .ChildKeyColumn("UserId")
            .Cascade.SaveUpdate()
            .Cache.ReadWrite();
        HasManyToMany(x => x.Permissions)
            .Table("GroupPermissions")
            .ParentKeyColumn("GroupId")
            .ChildKeyColumn("ClaimId")
            .Cascade.SaveUpdate()
            .Cache.ReadWrite();
    }
}

现在想加载所有用户和权限的所有组,但是我要进入选择n + 1问题。

我的查询是这样:

public async Task<IEnumerable<GroupDto>> Handle(GetAllGroupsQuery request, CancellationToken cancellationToken)
    {
        using var transaction =  _session.BeginTransaction();

        var query = await _session.QueryOver<Group>()
            .Fetch(SelectMode.Fetch, group => group.Permissions)
            .Cacheable()
            .ListAsync<Group>(cancellationToken);

        var membersQuery = await _session.QueryOver<User>()
            .Fetch(SelectMode.Fetch, user => user.Permissions)
            .JoinQueryOver<Group>(x=>x.Groups)
            .WhereRestrictionOn(x=>x.Id).IsIn(query.Select(y=>y.Id).ToList())
            .Cacheable()
            .ListAsync<User>(cancellationToken);

        var result = _mapper.Map<IEnumerable<GroupDto>>(query);
        await transaction.CommitAsync(cancellationToken);

        return result;
    }

在这种情况下如何避免选择n + 1?谢谢

nhibernate fetch queryover select-n-plus-1
1个回答
0
投票

尝试一下:

var groups = _session.Query<Group>()
    .Fetch(g => g.Permissions)
    .Fetch(g => g.Users)
    .ToList();

注意:这是使用LINQ API,而不是QueryOver。

© www.soinside.com 2019 - 2024. All rights reserved.