Как взять этот SQL-запрос и превратить его в запрос nhibernate - PullRequest
2 голосов
/ 22 апреля 2011

Я пытаюсь взять этот sql-запрос и превратить его в Hhibernate-HQL-запрос.Я использую nhibernate 3 и Fluent Nhibernate 1.2

SELECT     dbo.Tasks.CourseId, dbo.CoursePermissions.BackgroundColor, dbo.Tasks.DueDate, dbo.Tasks.TaskName, dbo.Tasks.TaskId
FROM         dbo.Courses INNER JOIN
                      dbo.Tasks ON dbo.Courses.CourseId = dbo.Tasks.CourseId INNER JOIN
                      dbo.CoursePermissions ON dbo.Courses.CourseId = dbo.CoursePermissions.CourseId
WHERE     (dbo.Tasks.CourseId = 1)

Мне бы хотелось использовать linq, но я не думаю, что nhibernate поддерживает объединения linq, поэтому я думаю, что я застрял с использованием HQL (если кто-то не знаетлучший путь).

Полагаю, я могу использовать QueryOver или другие способы, которыми nhibernate выполняет запросы, чтобы все работало лучше.Я до сих пор не понимаю разницу между всеми способами, как если бы я мог делать все в linq.

Однако я не знаю, как написать свой запрос.

Спасибо

Редактировать

Теперь у меня есть это (немного изменилось)

Course cAlias ​​= null;Task tAlias ​​= null;CoursePermission cpAlias ​​= null;

    var result = session.QueryOver<Task>(() => tAlias)
        .JoinAlias(() => tAlias.Course, () => cAlias)
        .JoinAlias(() => cAlias.CoursePermissions, () => cpAlias)
        .Where(Restrictions.In(Projections.Property(() => cAlias.Id), courseIds))
        .And(x => x.DueDate >= startDate)
        .And(x => x.DueDate <= endDate)
        .Select( Projections.Property(() => cAlias.Id),
                Projections.Property(() => cpAlias.BackgroundColor),
                Projections.Property(() => tAlias.DueDate),
                Projections.Property(() => tAlias.TaskName),
                Projections.Property(() => tAlias.TaskId))
        .List<object[]>();

Я знаю, хочу отобразить его на

открытый класс TaskAppointments {public int Id {get;задавать;} публичная строка BackgroundColor {get;задавать;} public DateTime DueDate {get;задавать;} public int TaskId {get;задавать;} публичная строка TaskName {get;задавать;}

}

Как мне это сделать.Если бы это был метод linq, я бы сделал

.Select(new TaskAppointments { TaskId = Projections.Property(() => tAlias.TaskId)})

, но он говорит, что не может преобразовать его в целое число.

Edit2

Это то, что я придумал

Course cAlias ​​= null;Task tAlias ​​= null;CoursePermission cpAlias ​​= null;TaskAppointments taskAppointments = null;

    List<TaskAppointments> result = session.QueryOver<Task>(() => tAlias)
        .JoinAlias(() => tAlias.Course, () => cAlias)
        .JoinAlias(() => cAlias.CoursePermissions, () => cpAlias)
        .Where(Restrictions.In(Projections.Property(() => cAlias.Id), courseIds))
        .And(x => x.DueDate >= startDate)
        .And(x => x.DueDate <= endDate)
        .SelectList(list => 

                            list.SelectGroup(x => x.TaskId).WithAlias(() => taskAppointments.TaskId)
                            .SelectGroup(() => cpAlias.BackgroundColor).WithAlias(() => taskAppointments.BackgroundColor)
                            .SelectGroup(x => x.DueDate).WithAlias(() => taskAppointments.DueDate)
                            .SelectGroup(x => x.TaskName).WithAlias(() => taskAppointments.TaskName)
                    )
        .TransformUsing(Transformers.AliasToBean<TaskAppointments>())
        .List<TaskAppointments>().ToList();

1 Ответ

3 голосов
/ 23 апреля 2011

Без сопоставлений я предполагаю, что у вас есть следующие отношения: Courses -> Tasks (1: n) и Courses -> CoursePermissions (1: n) Я также предположил, что вы не хотитеполные объекты, но только определенные свойства, поэтому я использовал проекции.

Версия QueryOver:

// the aliases are required here, so that we can reference the entities properly
Courses cAlias = null;
Tasks tAlias = null;
CoursePermissions cpAlias = null;

var result = session.QueryOver<Courses>(() => cAlias)
    .JoinAlias(() => cAlias.Tasks, () => tAlias)
    .JoinAlias(() => cAlias.CoursePermissions, () => cpAlias)
    .Where(() => cAlias.CourseId == 1)
    .Select(Projections.Property(() => cAlias.CourseId),
            Projections.Property(()  => cpAlias.BackgroundColor),
            Projections.Property(()  => tAlias.DueDate),
            Projections.Property(()  => tAlias.TaskName),
            Projections.Property(()  => tAlias.TaskId))
    .List<object[]>();

Изменить начало

Если вам нужно сделатьГДЕ В предложении, вы можете сделать это:

List<int> courseIdList = new List<int>() { 1, 2 };

var result = session.QueryOver<Courses>(() => cAlias)
    .JoinAlias(() => cAlias.Tasks, () => tAlias)
    .JoinAlias(() => cAlias.CoursePermissions, () => cpAlias)
    .Where(Restrictions.In(Projections.Property(() => cAlias.CourseId), courseIdList))
    .Select(...)
    .List<object[]>();

Редактировать конец

Редактировать 2 начало

Если вы хотитечтобы преобразовать его в DTO:

// AliasToBeanResultTransformer is in namespace NHibernate.Transform
// we have to use .As("...") for the transformer to find the correct property-names
var result = ...
    .Select(Projections.Property(() => cAlias.CourseId).As("CourseId"),
            Projections.Property(()  => cpAlias.BackgroundColor).As("BackgroundColor"),
            Projections.Property(()  => tAlias.DueDate).As("DueDate"),
            Projections.Property(()  => tAlias.TaskName).As("TaskName"),
            Projections.Property(()  => tAlias.TaskId).As("TaskId"))
    .TransformUsing(new AliasToBeanResultTransformer(typeof(TaskAppointments)))
    .List<TaskAppointments>();

Изменить 2 end

Версия HQL:

string hql = "select c.CourseId, cp.BackgroundColor, t.DueDate, t.TaskName, t.TaskId" 
   + " from Courses as c inner join c.Tasks as t inner join c.CoursePermissions as cp" 
   + " where c.CourseId = 1";

var result2 = session.CreateQuery(hql)
    .List<object[]>();

Имейте в виду, что это приведет кдекартово произведение, поэтому для каждого курса вы получите строки Tasks.Count + CoursePermissions.Count.

...