AutoQuery:通过中间表连接表并定义要加入的FK

时间:2016-05-02 01:01:32

标签: servicestack ormlite-servicestack autoquery-servicestack

我们最近开始使用ServiceStack AutoQuery。这是一个很好的功能,我们非常喜欢它。我们有这样的表结构(缩小版本以便于阅读):

Salary [Id (PK), ManagerId (FK)] 
Manager [Id (PK), DepartmentId (FK)] /* Manager is like Employee table even thought it's named Manager */
Department [Id (PK), ActiveManagerId (FK)] /* The FK ActiveManagerId is supposed to be a shortcut, it's Nullable.  */

所以理论上我们可以像这样加入

Salary -> Manager via Salary.ManagerId = Manager.Id
Manager -> Department via Manager.DepartmentId = Department.Id
Department -> Manager via Department.ActiveManagerId = Manager.Id

但是在这种特定情况下,如果我们通过Department.ActiveManagerId = Manager.Id从Department加入Manager,将无法生成正确的结果,因为Department.ActiveManagerId是一个快捷方式,专为其他场景设计。

所以当我像这样定义AutoQuery时

public class SalaryQuery : QueryBase<Salary, SalaryQueryResult>,
 ILeftJoin<Salary, Manager, Department>

下面的SQL是由AutoQuery生成的,从ServiceStack AutoQuery的角度来看是正确的。

select  s.Id
    ,   d.Id
from    Salary s
    left join
        Manager m
    on  s.ManagerId = m.Id
    left join
        Department d
    on  d.ActiveManagerId = m.Id /* should NOT use shortcut: Department -> Manager via Department.ActiveManagerId = Manager.Id */

但我们希望能够生成类似于

的SQL
select  s.Id
    ,   d.Id
from    Salary s
    left join
        Manager m
    on  s.ManagerId = m.id
    left join
        Department d
    on  d.Id = m.DepartmentId /* should use the desired FK: Manager -> Department via Manager.DepartmentId = Department.Id */

1 个答案:

答案 0 :(得分:3)

如果你想要不同的JOIN行为,你需要在Custom AutoQuery implementation中添加自定义LEFT JOIN,例如:

//AutoQuery DTO
public class SalaryQuery : QueryDb<Salary,SalaryQueryResult>, ILeftJoin<Salary,Manager>

//Implementation
public class MyServices : Service
{
    public IAutoQueryDb AutoQuery { get; set; }

    public object Any(SalaryQuery query)
    {
        var q = AutoQuery.CreateQuery(query, base.Request)
            .LeftJoin<Manager, Department>((m, d) => d.Id == m.DepartmentId);

        return AutoQuery.Execute(query, q);
    } 
}
  

注意:从v4.0.56开始,QueryBase<T>deprecated and renamed to QueryDb