我有一个我正在尝试运行的查询,但我没有得到理想的结果。
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 Table的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 :(得分: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方法,而不是会话)。你应该只需要这个位进行测试(在我的测试中,数据库只在会话中存在)。如果您希望以这种方式解决问题,那么gist中还有一个QueryOver示例。