3

最近ServiceStack AutoQueryを使用し始めました。それは素晴らしい機能であり、私たちは本当にそれを楽しんだ。私たちはから参加する場合AutoQuery:中間テーブルを介してテーブルを結合し、結合するFKを定義する

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.ActiveManagerIdがショートカットであり、他のシナリオ用に設計されているため、正しい結果を生成しません。

は、だから私は、SQLがServiceStack AUTOQUERYの観点から正しいとするAUTOQUERYによって生成された下にはそう

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

よう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 */ 

しかし、その代わりに、我々はあなたが異なるが、カスタムLEFTを追加する必要があります行動に参加したい場合は、この

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 */ 

答えて

3

のように見えるSQLを生成する能力を望んでCustom AutoQuery implementation、例えばに参加:

//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); 
    } 
} 

注:deprecated and renamed to QueryDbてきたQueryBase<T> v4.0.56から。

+1

私はマニュアルでサービスの実装を書かなくても済むように、手動で結合ONを定義できるようにするための属性があることを期待していました。 OK。私は提案された方法でやります。ありがとう@マイミー。 – Jeff

+0

AQにバグがある可能性がある(柔軟すぎる)と思います。 C#でDepartment.ActiveManagerIdにForeignKey属性が宣言されている場合、生成されたsqlは元の質問のON(d.ActiveManagerId = m.Id) - 1st sqlに参加しますが、Department.ActiveManagerIdでForeignKeyを削除すると、 ONに参加する(d.Id = m.DepartmentId) - 元の質問の2番目のsql。 Manager.DepartmentId(C#の場合)にはForeignKey属性も宣言されているためです。では、なぜAQは結合宣言が同じままであれば(すなわち、ILeftJoin )、異なる結合ONを生成するのでしょうか? – Jeff

+1

@Jeff [ForeignKeyとReferences属性は参照を定義する優先順位があるため](https://github.com/ServiceStack/ServiceStack.OrmLite#foreign-key-and-references-attributes)。 – mythz

関連する問題