簡體   English   中英

在Nhibernate條件或Nhibernate Linq中加入查詢

[英]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出勤結果視圖中。 如何實現這兩件事?

  1. 雇員和雇員出勤率的左聯接(雇員是左表)
  2. 聯接的條件和條件不超過聯接結果。

對於使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM