2016-10-28 2 views
0

私は次のSQLクエリと同等のものを実行するために滑らかな3.1.1を使用しようとしている:このクエリを滑らかに表現する方が、より読みやすく、慣用的な表現方法がありますか?

SELECT 
    r.* 
FROM Resource r 
INNER JOIN User u ON u.id = r.owner_id 
INNER JOIN UserCredentials uc ON uc.user_id = u.id 
WHERE r.id = <resource id> 

私はこのようなクエリを表明しました:

(for (((resource,_),_) <- resources 
           join users on (_.userId === _.id) 
           join userCredentials on (_._2.id === _.userId)) 
    yield resource).filter(_.id === resourceId).result.headOption 

それはunwieldlyとハードな感じ読む。このクエリを滑らかに書くためのよりクリーンな方法がありますか?

答えて

0

救助の理解のため。内部ジョインとクロスジョインは、「モナドジョイン」として表すことができます。以下は内部結合を使用しています:

val query = for { 
    r <- resources if r.id === resourceId 
    u <- users if u.id === r.ownerId 
    uc <- userCredentials if uc.userId === u.id 
} yield r 

さらに多くの例については、slick docsを参照してください。

0

私は個人的に行名を表示するために、部分的な機能を使用して、メソッド・スタイルを好む:

resources.filter(_.id === resourceId).join(users).on { 
    case (resource, user) => resource.userId === user.id 
}.join(userCredentials).on { 
    case ((_, user), userCredentials) => user.id === userCredentials.userId 
}.filter { 
    case ((resource, _), _) => resource.id === resourceId 
}.map { 
    case ((resource, _), _) => resource 
}.result.headOption 

あなたはまた、事が少しきれいになり、あなたの最初のステップとして、resourcesをフィルタリングすることができます:

resources.filter(_.id === resourceId).join(users).on { 
    case (resource, user) => resource.userId === user.id 
}.join(userCredentials).on { 
    case ((_, user), userCredentials) => user.id === userCredentials.userId 
}.map { 
    case ((resource, _), _) => resource 
}.result.headOption 

を私はそれが助けて欲しい!

関連する問題