我有这个模特:
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?谢谢
尝试一下:
var groups = _session.Query<Group>()
.Fetch(g => g.Permissions)
.Fetch(g => g.Users)
.ToList();
注意:这是使用LINQ API,而不是QueryOver。