ServiceStack, запрос LeftJoin

У меня есть этот код SQL, и я хочу, чтобы он был преобразован в ormlite - но я не знаю, как это сделать наилучшим образом.

SELECT  *
FROM Job 
INNER JOIN Emp ON Job.JobAnsvarID = Emp.EmpId
LEFT JOIN (SELECT JobId, MIN(TimeReg.RegDate) AS TimeMinDate FROM TimeReg WHERE RegHrs IS NOT NULL AND JournNo = 0 GROUP BY JobId) AS t ON t.JobId = Job.JobID
WHERE   NOT (t.TimeMinDate IS NULL)

Я знаю, что могу использовать CustomJoin и UnsafeWhere, но, если возможно, я хочу избегать использования жестко закодированного текста.

Прямо сейчас у меня есть это, но опять же, я хочу избежать жестко закодированного текста.

var ev = Db.From<Job>();
ev.CustomJoin("LEFT JOIN (SELECT {TimeReg.JobId}, MIN({TimeReg.RegDate}) AS MinDate FROM {TimeReg} WHERE {TimeReg.RegHrs} IS NOT NULL AND {TimeReg.JournNo} = 0 GROUP BY {TimeReg.JobId}) AS t ON t.JobId = {Job.JobID}"
            .ReplaceAll("{Job.JobID}", GetQuotedColumnName<Job>(x => x.Id, true))
            .ReplaceAll("{TimeReg.JobId}", GetQuotedColumnName<TimeRegDTO>(x=>x.JobId, true))
            .ReplaceAll("{TimeReg.RegDate}", GetQuotedColumnName<TimeRegDTO>(x => x.RegistrationDate, true))
            .ReplaceAll("{TimeReg.RegHrs}", GetQuotedColumnName<TimeRegDTO>(x => x.Hours, true))
            .ReplaceAll("{TimeReg.JournNo}", GetQuotedColumnName<TimeRegDTO>(x => x.JournalNumber, true))
            .ReplaceAll("{TimeReg}", GetQuotedTableName<TimeRegDTO>()));

GetQuotedColumnName просто берет имя псевдонима из DTO и использует это

1 ответ

Решение

Ни один OrmLite не имеет типизированного API для пользовательских объединений в подзапросах только в запросах SubSelect.

Вместо замены HTML я бы просто использовал интерполяцию строк C#, также мог бы использовать более простой типизированный подход nameofНапример:

var q = Db.From<Job>();
q.CustomJoin($"LEFT JOIN (SELECT {nameof(Job.Id)} ...")

Который вы сможете использовать, если ваши свойства не имеют псевдонимов или вы используете пользовательское соглашение об именах.

В противном случае, чтобы сделать вариант использования для этого немного лучше, я добавил новый .Column<Table>() а также .Table<T>() методы расширения в этом коммите, которые позволят вам использовать Typed APIs в вашем пользовательском SQL, например:

q.CustomJoin($"LEFT JOIN (SELECT {q.Column<Job>(x => x.Id)} ...")
q.CustomJoin($"LEFT JOIN (SELECT {q.Column<Job>(nameof(Job.Id))} ...")

q.CustomJoin($"LEFT JOIN (SELECT {q.Column<Job>(x => x.Id, tablePrefix:true)} ...")
//Equivalent to:
q.CustomJoin($"LEFT JOIN (SELECT {q.Table<Job>()}.{q.Column<Job>(x => x.Id)} ...")

Это изменение доступно с версии 5.0.3, которая теперь доступна на MyGet.

Другие вопросы по тегам