繁体   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