ServiceStack,LeftJoin查询

时间:2018-01-11 19:49:54

标签: c# servicestack ormlite-servicestack

我有这个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 个答案:

答案 0 :(得分:2)

没有OrmLite在子查询上没有自定义联接的类型化API IN SubSelect queries

我不会替换HTML,而只使用C#字符串插值,更简单的Typed方法可能是使用nameof,例如:

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

如果您的属性没有别名或者您使用的是自定义命名约定,那么您就可以使用它。

除非为了更好地使用这个用例,我在this commit中添加了新的.Column<Table>().Table<T>()扩展方法,这些方法可以让您使用类型化的API自定义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)} ...")

此更改现在可从v5.0.3获取,现在为available on MyGet