Запрос на присоединение по критериям Nhibernate или в Nhibernate Linq - PullRequest
0 голосов
/ 11 января 2012

У меня есть запрос, который я пытаюсь выполнить, но я не получаю желаемого результата.

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 посещаемость результатов просмотра.Как я могу достичь этих двух вещей?

  1. левое соединение по сотруднику и сотруднику (таблица слева - работник)
  2. a и условие объединения не связано с результатом объединения.

Я довольно новичок в этой ситуации, используя 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имеет внешний ключ в качестве EmpId из таблицы сотрудников

Редактировать: я пытался это также в моей последней попытке:

 ICriteria criteria = session.CreateCriteria(typeof(Employee), "emp")
                     .CreateAlias("EmployeeAttendance", "Attendance", CriteriaSpecification.LeftJoin
                     , Restrictions.Eq("Attendance.Dated", DateTime.Parse("2012-1-11")));

, но я в итоге получил ошибку как:

не удалось разрешить свойство: EmployeeAttendance of: Royal.Data.Core.Domain.Employee

1 Ответ

1 голос
/ 11 января 2012

Похоже, вы хотите, чтобы сотрудники ушли в отпуск на определенную дату.Я думаю, что это сработает, хотя я никогда раньше не использовал выражение «между» таким образом:

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, если вы хотите решить его таким образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...