[英]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.