使用Slick的提升嵌入,我定义了一个扩展AbstractTable的类,其中一些主键跨越多个列。例如:
class Foo extends AbstractTable[(some, tuple, type)](tag, name)
{
def col1 = ...
def col2 = ...
def col3 = ...
def * = (col1, col2, col3)
def pk = primaryKey(name, (col1, col2))
...
}
在代码中的某处,我持有一个与该主键相对应的PrimaryKey引用(所讨论的代码是通用的,并且不得依赖于知道哪些特定表以及定义了哪些列)。我还引用了对应于此表中一行的TableElementType元组,由* projection定义。
如何以编程方式获取该元素的主键投影?也就是说,给定PrimaryKey和TableElementType引用作为参数,我想在这个例子中从(val1,val2,val3)TableElementType元组中获取(val1,val2)元组。我没有找到现成的方法来实现Slick文档。
答案 0 :(得分:0)
AbstractTable
具有不同的签名,它需要3个参数而不是2:
abstract class AbstractTable[T](val tableTag: Tag, val schemaName: Option[String], val tableName: String) extends ColumnBase[T]
我为了方便而延伸Table
,您可以做的是扭曲表格类型参数中的形状:
class Foo(tag: Tag) extends Table[((String, String), String)](tag, "Foo") {
def col1 = column[String]("c1")
def col2 = column[String]("c2")
def col3 = column[String]("c3")
def * = ((col1, col2), col3)
def pk = primaryKey("pk", (col1, col2))
}
请注意,如果您有(String, String, String)
,则还必须定义投影函数:
def * = (col1, col2, col3)
// this below doesn't match the given shape:
// def * = ((col1, col2), col3)
如果您不想,只需定义自定义方法:
def someF(results: List[(String, String, String)]): List[((String, String), String)] = {
results.map { case(a,b,c) => ((a,b),c) }
}
代码未经测试,因为目前我没有可用的数据库,但它会编译。
编辑:
你可以用这个:
def tupleKeys[T <: Table[S], S](table: TableQuery[T]): Tuple2[Option[PrimaryKey], Option[PrimaryKey]] = {
val keys: List[PrimaryKey] = table.baseTableRow.primaryKeys.toList
if(keys.length == 2) (Option(keys(0)), Option(keys(1)))
else (Option(keys(0)), None)
}
但正如我所说的那样,在元组长度固定的情况下,你不知道在运行脚本之前有多少键,我将值包装在选项中,因为你可能有或没有2个键,你可以返回Tuple1
或Tuple2
因为它们是不同的类型,您可以将此方法用于投影功能以扭曲键形状,但它仍然不会像您想要的那样动态。