2012-01-11 54 views
0

我有一個查詢我試圖運行,但我沒有得到想要的結果。加入查詢在Nhibernate標準或在Nhibernate Linq

select * from employee_login e 
left join employee_attendance ea on 
e.emp_id = ea.EmpId and dated = '2012-01-11' 

LINQ查詢我與NHibernate的嘗試是

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出席resultview。我怎樣才能做到這兩件事?

  1. 左連接在僱員和employeeattendance(僱員是左表)
  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();   
    } 
} 

員工是主表和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

+0

'select * from employee_login e left join employee_attendance ea on e.emp_id = ea.EmpId and ea。日期= '2012-01-11'' 應相當於 'SELECT * FROM employee_loginê 留在 e.emp_id = ea.EmpId 加入employee_attendance EA其中ea.dated =' 2012-01-11 「'。您的模型中的Employee類和EmployeeAttendance之間是否存在關聯? – Firo 2012-01-11 11:48:16

+0

@Firo對不起,我忘了把域。是的,在EmpId是外鍵 – Joy 2012-01-11 12:37:45

回答

1

它看起來像你想休假的員工截至某個日期。我認爲這會工作,但我從未使用過的表達與這樣:

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>(); 

這似乎是工作 - 但你需要確保你回來是實體沒有被緩存,否則緩存的副本將會返回完整的集合。 This是我測試過的 - 不完全像你的情況,因爲集合是通過鏈接表來維護的,但我認爲它會以同樣的方式工作 - 你可能需要用直接的一對多的方式驅逐集合(EvictCollection方法在會話工廠中找到,而不是會話)。你只需要這一點就可以進行測試(在我的測試中,數據庫只與會話一樣長)。如果您希望以這種方式解決問題,那麼在要點中還有一個QueryOver示例。

+0

的模型中,員工類和EmployeeAttendance之間存在關聯,您已經有了相當多的情景。事情是我想要得到所有員工這就是爲什麼我離開加入從員工到員工考勤並獲得他們的地位。即使在這種情況下沒有出席在右表中的參加者,它將在特定的日期返回僱員,但如果在該特定日期沒有出席,那麼它應該在出席字段上返回空值。 – Joy 2012-01-12 04:18:54

+0

http://stackoverflow.com/questions/2756148/nhibernate-left-outer-加入此鏈接是我想要做的確切匹配。他給出了一個解決方案,但我沒有得到如何使它的工作。我的意思是如何執行它。你能幫我解決嗎? – Joy 2012-01-12 05:25:00

+0

查看我剛發佈的更新,我認爲它會做你想做的 - 只要注意提到的緩存問題。 – AlexCuse 2012-01-15 01:07:28