加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – NHibernate QueryOver WhereExists on Many-to-Many

发布时间:2020-12-16 01:43:41 所属栏目:百科 来源:网络整理
导读:我有一个多对多的关系,我试图查询.我的问题非常类似于菲利普·海顿 here所详述的问题,所以我将自由地借用他的图表和解释. Phillip在Jobs和Roles之间有以下多对多的关系(抱歉我还无法嵌入图片): data schema Phillip需要查询未分配给作业的所有角色.他的解决
我有一个多对多的关系,我试图查询.我的问题非常类似于菲利普·海顿 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和角色. JobRole既有工作又有角色.可能是这样的:

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中的select的投影,如果没有提供则抱怨,这对我来说很有意义.

使用我的模型甚至可以使用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)

并返回只有您想要的角色的作业

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读