Scala 如何获取TableElementType元组的PrimaryKey投影?

Scala 如何获取TableElementType元组的PrimaryKey投影?,scala,slick,Scala,Slick,使用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)) ... }

使用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元组的引用,该元组对应于该表中的一行,由*投影定义


如何以编程方式获取该元素的主键投影?也就是说,给定PrimaryKey和TableElementType引用作为参数,在本例中,我希望从(val1,val2,val3)TableElementType元组中获取(val1,val2)元组。我在光滑的文档中找不到现成的方法来实现这一点。

AbstractTable具有不同的特征,它需要3个参数,而不是2个:

abstract class AbstractTable[T](val tableTag: Tag, val schemaName: Option[String], val tableName: String) extends ColumnBase[T]
这里我扩展了
表格
,为了方便起见,您可以在表格类型参数中扭曲形状:

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

def tupleKeys[T谢谢,但这并不是我想要的。我甚至还没有开始为具体的表编写类(而且暂时不会)。我正在编写一个通用数据访问层,我对获取主键投影的通用方法感兴趣。类似于通用类中的一个方法,它接受两个参数PrimaryKey和T#TableElementType,并仅为主键中包含的列返回给定元素的值的元组。你问什么由于它在其类型中编码的元组长度(例如
Tuple2
Tuple3
等等),因此很难实现迭代,您可以定义一个表对象并在迭代器中获取主键:
TableQuery[Foo].baseTableRow.primaryKeys
,从这里开始,我不能告诉你如何将其变为元组,可能Shapess有一些相关的东西,但我不是该库的专家。好的,我明白了。我确实迭代了主键。一个更简单的问题如何?比如,我有一个t#TableElementType元素和一个列[V]列。如何以编程方式获取该元素的列值?苹果和橘子在我看来,
TableElementType
是数据库的行表示形式(例如,通过投影函数获得的),
Column
用于创建表抽象,尽管它们引用的是以不同方式派生的同一实体,而且据我所知,两者之间没有明确的关系,但就我所知,slick使用一些AST来转换SQL中类似集合的操作(无列)。如果您已经有一行,那么您已经有了表定义中指定的任何形状的值。那么如何从行中检索该值呢?我不能调用elem.col1,因为代码没有访问该类的权限,因此不知道col1方法是否存在。除了该行之外,我所拥有的是一个PrimaryKey实例,我在该实例上可以调用key.columns并遍历这些列。