我有一个我试图查询的多对多关系。我的问题与 Phillip Haydon here 详述的问题非常相似,因此我将大量借用他的图表和解释。

Phillip 在 Jobs 和 Roles 之间有以下多对多关系(抱歉,我还不能嵌入图像):
data schema

Phillip 需要查询所有未分配给作业的角色。他的解决方案如下:

Role roleAlias = null;

var existing = QueryOver.Of<JobRole>()
                    .Where(x => x.Job.JobId == jobId)
                    .And(x => x.Role.RoleId != roleId)
                    .And(x => x.Role.RoleId == roleAlias.RoleId)
                    .Select(x => x.Role);

result = Session.QueryOver<Role>(() => roleAlias)
            .Where(x => x.IsEnabled)
            .WithSubquery.WhereNotExists(existing)
            .OrderBy(x => x.Name).Asc
            .List();

这非常有帮助,但似乎在此解决方案中,每个表都有一个实体;工作、工作角色和角色。 JobRole 有一个 Job 和一个 Role。大概是这样的:
public class Job
{
  public int JobId {get;set;}
  public string Name {get; set;}
  public bool IsEnabled {get;set;}
  public bool IsDefault {get;set;}
}

public class Role
{
  public int RoleId {get;set}
  public string Name  {get;set}
  public bool IsEnabled {get;set}
  public string RoleType {get;set}
}

public class JobRole
{
  public Job Job {get;set}
  public Role Role {get;set;}
}

这与我看到的多对多关系建模模式相冲突,特别是在清晰的架构示例和此处的建议中。在这些例子和我的例子中,我只有两个类,Job 和 Role。像这样的东西:
public class Job
{
  public int JobId {get;set;}
  public string Name {get; set;}
  public bool IsEnabled {get;set;}
  public bool IsDefault {get;set;}
  public IList<Role> Roles {get;set;}
}

public class Role
{
  public int RoleId {get;set}
  public string Name  {get;set}
  public bool IsEnabled {get;set}
  public string RoleType {get;set}
  public List<Job> Jobs {get;set;}
}

就我而言,我需要找到所有只有角色的工作。我试过这样的事情
  Job job = null;
  Role role = null;

  var jobs = Session.QueryOver(() => job)
                    .WithSubquery
                    .WhereExists(
                          QueryOver.Of(() => role)
                          .JoinAlias(() => role.Jobs, () => job))
                    .List().ToList();

但是 NHibernate 要求对 WhereExists 中的选择进行投影,如果未提供,则会提示,这对我来说很有意义。

使用我的模型,甚至可以使用 WhereExists 执行 QueryOver 子查询吗?

提前致谢。

最佳答案

var jobs = session
     .QueryOver<Job>()
     .WhereRestrictionOn(j => j.Roles)
         .IsNotEmpty
     .List();

工作映射:
 public class Job
    {
        public virtual int ID { get; set; }
        public virtual string Name { get; set; }
        public virtual IList<Role> Roles { get; set; }
    }

和映射
 <class name="Job">
       ...
       <bag name="Roles" table="JobRoleMap" fetch="join" lazy="false" >
          <key column="JobID" />
          <many-to-many column="RoleID" class="Role" />
       </bag>
    </class>

在我的情况下,产生以下 SQL(美化):
SELECT j.ID,
       j.Name,
       roles.JobID,
       r.ID,
       r.Name
FROM   Job j
       left outer join JobRoleMap roles
         on j.ID = roles.JobID
       left outer join Role r
         on roles.RoleID = r.ID
WHERE  exists (select 1
               from   JobRoleMap
               where  j.ID = JobID)

并仅返回具有您想要的角色的工作

关于c# - NHibernate QueryOver WhereExists on Many-to-Many,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5890362/

10-10 11:12