问题
What I'm looking for seems fairly common but I can't seem to figure it out through the Squeryl api. I need to have a conditional piece to my on statement for a join.
def getAllJoined(
hasFallback:Option[String] = None
):List[(Type1,Type2)] = transaction{
join(mainTable,
table2,
table3,
table3,
table4.leftOuter,
table4.leftOuter,
table5,
table6)((main, attr1, attr2, attr3, attr4, attr5, attr6, attr7) =>
select(main,attr1,attr2,attr3,attr4,attr5,attr6,attr7)
on(
//if(hasFallback.isDefined) (main.fallBack).isNotNull else 1 === 1.inhibitWhen(true)
(main.attr1Col === attr1.id) ,
(main.attr2Col === attr2.id) ,
(main.attr3Col === attr3.id) ,
(main.attr4Col === attr4.map(_.id)) ,
(main.attr5Col === attr5.map(_.id)) ,
(main.attr6Col === attr6.id) ,
(main.attr7Col === attr7.id)
)
).toList
I'm not sure how I could get this. I've thought about things like tacking on another on, or doing what I have commented here.
The bottom line is basically if I have this hasFallback flag on, I need to only return objects that have this column not null (defined). Otherwise if the hasFallback flag isn't there, ignore if it's defined or not.
EDIT: It looks like the on method can only take seven parameters. Is there a way around this seven parameter limit?
Also, type mismatch; found : org.squeryl.dsl.boilerplate.JoinQueryYield6[myTuple] required: org.squeryl.dsl.boilerplate.JoinQueryYield7[?]
So apparently I'm being forced to have 7 some reason no matter what? No more or no less.
Directly from the squeryl site
If a join has N arguments, the ‘on’ function must take N-1 arguments, the i’th ‘on’ condition corresponds to the i’th table expression :
join(T, A1, A2,... AN)((a1,a2,...,aN) =>
...
on(...condition for a1...,...condition for a2...,......condition for aN..., )
)
SOLUTION: For anyone else that landed here with the same problem, here is the solution using a where clause.
...table6)((main, attr1, attr2, attr3, attr4, attr5, attr6, attr7) =>
where(
main.fallBack.isNotNull.inhibitWhen(!hasFallback.isDefined)
)
select(main,attr1,attr2,attr3,attr4,attr5,attr6,attr7)...
回答1:
If you are simply looking to add a conditional to your where clause, you can do something like this:
on(
t1.secondary === t2.id and
(if(hasFallback.isDefined) t1.fallback.isNotNull else 1 === 1.inhibitWhen(true))
)
The inhibitWhen
clause should always prevent the output of 1 === 1
from showing up in the actual SQL, but it allows your if/else to return a LogicalBoolean
.
回答2:
There is a talk related to a similar question on github and a google group:
https://github.com/max-l/Squeryl/pull/168
https://github.com/max-l/Squeryl/pull/144
https://groups.google.com/forum/#!topic/squeryl/BBAXbtRq9v4
If you're using squeryl-0.9.5-6, then you should find a way out by your own. I chose to do (a similar task) the following way:
/** thin wrappwer with no runtime cost */
implicit class RichLogicalBoolean(val e: LogicalBoolean) extends AnyVal {
def and(condition: Boolean, other: LogicalBoolean) = if (condition) other and e else e
}
after this, I can write a code like:
t1.secondary === t2.id and
(yourCondition, t1.fallback.isNotNull)
来源:https://stackoverflow.com/questions/17222246/squeryl-dynamic-join-clauses