.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()
}
}
}