[英]Join query in Nhibernate criteria or in Nhibernate Linq
我有一个尝试运行的查询,但没有得到想要的结果。
select * from employee_login e
left join employee_attendance ea on
e.emp_id = ea.EmpId and dated = '2012-01-11'
我用Nhibernate尝试过的Linq查询是
var attendance = from emp in session.Query<Employee>()
join empatten in session.Query<EmployeeAttendance>()
on emp.emp_id equals empatten.EmpId into atts
from ur in atts.DefaultIfEmpty()
select new { ur };
在var出勤结果视图中。 如何实现这两件事?
对于使用Linq或独立标准的这种情况,我还是很陌生。 一个独立的标准将是一个更好的答案。
这些是模型:
public class EmployeeAttendance
{
public virtual string No_ { get; set; }
public virtual Employee Employee { get; set; }
}
public class Employee
{
public virtual string emp_id { get; set; }
public virtual ISet<EmployeeAttendance> Attendances { get; set; }
public Employee()
{
Attendances = new HashedSet<EmployeeAttendance>();
}
}
映射为:
public class EmployeeAttendanceMap:ClassMap<EmployeeAttendance>
{
public EmployeeAttendanceMap()
{
Table("Employee_Attendance");
Id(x => x.No_).GeneratedBy.Assigned();
References(x => x.Employee).Column("emp_id");
}
}
public class EmployeeMap : ClassMap<Employee>
{
public EmployeeMap()
{
Table("employee_login");
Id(x => x.emp_id).Column("emp_id").GeneratedBy.Assigned();
HasMany(x => x.Attendances).KeyColumn("No_").Cascade.All();
}
}
Employee是主表,AttendanceLeave从Employee表中将外键作为EmpId
编辑:我在上一次尝试中也尝试过此操作:
ICriteria criteria = session.CreateCriteria(typeof(Employee), "emp")
.CreateAlias("EmployeeAttendance", "Attendance", CriteriaSpecification.LeftJoin
, Restrictions.Eq("Attendance.Dated", DateTime.Parse("2012-1-11")));
但是我最终得到如下错误:
无法解析属性:EmployeeAttendance的:Royal.Data.Core.Domain.Employee
您似乎想让雇员在某个日期休假。 我认为这是可行的,尽管我以前从未以这种方式使用过间表达:
var detached = DetachedCriteria.For<AttendanceLeave>("al")
.Add(Expression.Between('2012-01-11', "LeaveFrom", "LeaveTo")) //this should be a DateTime
.Add(Restrictions.EqProperty ("al.EmpId", "e.emp_id")) //make sure to use "e" for employee criteria alias
.SetProjection (Projections.Count ("al.EmpId"));
var employeesOnLeave = session.CreateCriteria<Employee>("e")
.Add(Restrictions.Gt(Projections.Subquery(detached), 0))
.List();
您仍然可以在每位员工上获得完整的叶子,但是应该是您想要的员工。
更新 -查看您的评论,似乎是您所追求的:
DateTime dateInQuestion = new DateTime(2012, 1, 11);
var employeesOnLeaveAsOfDateInQuestion =
session.CreateCriteria<Employee>("e")
.CreateCriteria("e.Attendances", "ea"
, NHibernate.SqlCommand.JoinType.LeftOuterJoin
, Restrictions.Between(dateInQuestion, "ea.LeaveFrom", "ea.LeaveTo"))
.List<Employee>();
这似乎可行-但您需要确保不缓存取回的实体,否则将返回带有完整集合的缓存副本。 这就是我测试过的-与您的情况不完全相同,因为集合是通过链接表维护的,但是我认为这两种方法都可以工作-您可能需要直接将一对一逐出(EvictCollection方法在会话工厂(而不是会话)上找到)。 您只需要将此位用于测试(在我的测试中,数据库仅在会话中存在)。 要点中还有一个QueryOver示例,如果您希望以这种方式解决它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.