.net 如何使用NHibernate将子集合查询到嵌套集合?

.net 如何使用NHibernate将子集合查询到嵌套集合?,.net,nhibernate,.net,Nhibernate,鉴于以下结构: public class Contract { virtual int Id {get;set;} virtual IList<Course> Courses {get;set;} } public class Course { virtual int Id {get;set;} virtual IList<Schedule> Schedules {get;set;} } public class Schedule { virt

鉴于以下结构:

public class Contract
{
  virtual int Id {get;set;}
  virtual IList<Course> Courses {get;set;}
}

public class Course
{
  virtual int Id {get;set;}
  virtual IList<Schedule> Schedules {get;set;}  
}

public class Schedule
{
  virtual int Id {get;set;}
  virtual DateTime Start {get;set;}
  virtual DateTime End {get;set;}
}
你认为有一种方法可以一次查询所有的问题吗?这样更好吗 只需单独执行.NETforeach循环和查询


提前感谢。

我不确定这是如何映射到LINQ到NHibernate的,但HQL版本将符合以下要求:

FROM Contract cn WHERE EXISTS 
    (FROM cn.Courses cc WHERE EXISTS 
        (FROM cc.Schedules s WHERE s.Start < '2011/01/01'))
合同cn中存在的

(来自cn.cc,如有)
(摘自cc.附表s,其中s.开始<'2011/01/01'))
假设是“Contracts”集合,LINQ-y解决方案可能看起来像:

Contracts.Where(cn => cn.Courses.Any(cc => cc.Schedules.Any(s => s.Start < ...)));
Contracts.Where(cn=>cn.Courses.Any(cc=>cc.Schedules.Any(s=>s.Start<…));

但是我不知道LINQ提供者是否正确地翻译了它。

我通过递归地检查每一个来解决它。我不介意几乎N+1查询的可能性,因为我的数据查询次数不会超过5次(最多)。我仍然给出答案,因为他的HQL让我想到了使用
Any

foreach (Course course in contract.Courses)
{
    foreach (Schedule entry in course.Schedules)
    {
        Schedule schedule = entry;
        var query = from  c in Session.Query<Course>()
                    where c.Schedules.Any(x =>
                                              x.Day == schedule.Day &&
                                              (
                                                (x.EndDate < schedule.EndDate && x.StartDate > schedule.StartDate) ||
                                                (x.EndDate == schedule.EndDate && x.StartDate > schedule.StartDate)
                                                // about 10 more of these
                                              )
                                          )
                     select c;

        var conflicting = query.FirstOrDefault();
        if (conflicting != null)
        {
            DoStuff()
        }
    }
}
foreach(合同课程)
{
foreach(课程中的课程表条目。课程表)
{
时间表=条目;
var query=来自会话中的c.query()
其中c.Schedules.Any(x=>
x、 日期==日程安排。日期&&
(
(x.EndDateschedule.StartDate)||
(x.EndDate==schedule.EndDate&&x.StartDate>schedule.StartDate)
//大约还有10个
)
)
选择c;
var conflicting=query.FirstOrDefault();
if(冲突!=null)
{
多斯塔夫()
}
}
}

我尝试了类似的方法,但在使用集合作为参数时遇到了问题,例如,将数据库课程与我的集合进行比较。我不太明白您的问题陈述如何要求使用集合作为参数。HQL查询应该使用单个标量参数返回满足条件的所有契约。当然,您需要将“2011/01/01”替换为参数占位符,但没关系。我发送的不是一个标量日期(这是一个例子,如果引起误解,很抱歉),而是一组“时间表”,每个都有自己的开始和结束日期。还有一个问题:当你得到结果时,你需要根据与之匹配的时间表来区分合同列表,还是一个简单的列表就足够了?后者相对容易,前者可能需要单独的查询。最后,我只想知道是否有冲突的计划(即布尔返回值)。当用户为给定的课程创建一个新的时间表时,我只需要知道是否存在日期冲突的预先存在的时间表。很抱歉,如果我很密集,但这听起来像是用户在创建一个提供标准的时间表——开始日期和结束日期——所以标量参数仍然应该起作用。也就是说,如果您想一次检查多个计划,您也可以这样做,如果您愿意允许在计划被验证之前保留这些计划。请参阅我自己的答案。谢谢。:)
foreach (Course course in contract.Courses)
{
    foreach (Schedule entry in course.Schedules)
    {
        Schedule schedule = entry;
        var query = from  c in Session.Query<Course>()
                    where c.Schedules.Any(x =>
                                              x.Day == schedule.Day &&
                                              (
                                                (x.EndDate < schedule.EndDate && x.StartDate > schedule.StartDate) ||
                                                (x.EndDate == schedule.EndDate && x.StartDate > schedule.StartDate)
                                                // about 10 more of these
                                              )
                                          )
                     select c;

        var conflicting = query.FirstOrDefault();
        if (conflicting != null)
        {
            DoStuff()
        }
    }
}