2012-01-11 50 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