我正在使用Slick 3.0,以下是我的代码:
def registerMember(newMember: TeamMember): Future[Long] = {
db.run(
teamProfileTable.filter(u => u.ID === newMember.ID).result.headOption
).flatMap {
case None => Future(-1)
case _ => db.run(
(teamProfileTable returning teamProfileTable.map(_.staffID)) += newMember.toTeamRecord
)
}
}
这可能看起来不错。但是当有更多层次的回调时,代码可能变得难以阅读。我尝试使用for-expression
或andThen
简化代码。但由于模式匹配部分,我只能使用flatMap
来实现此功能。
有没有人有关于如何重构这个的想法?
答案 0 :(得分:2)
我认为理解在这里应该没问题,你只需要在第一个Option
的结果中对Future
进行条件处理。这样的东西应该工作(注意我没有编译检查这个):
def registerMember(newMember: TeamMember): Future[Long] = {
for{
r1Opt <- db.run(teamProfileTable.filter(u => u.ID === newMember.ID).result.headOption
r2 <- r1Opt.fold(Future.successful(-1L))(r1 => db.run((teamProfileTable returning teamProfileTable.map(_.staffID)) += newMember.toTeamRecord)
} yield r2
}
您可以在fold
的右侧看到我有权访问第一个Future
的结果,如果它是Some
(r1
)。
我甚至会更进一步,为理解的步骤创建单独的方法来清理,例如:
def registerMember(newMember: TeamMember): Future[Long] = {
def findMember =
db.run(teamProfileTable.filter(u => u.ID === newMember.ID).result.headOption
def addMember(r1Opt:Option[TeamMember]) = {
r1Opt.fold(Future.successful(-1L)){r1 =>
db.run((teamProfileTable returning teamProfileTable.map(_.staffID)) +=
newMember.toTeamRecord)
}
}
for{
r1Opt <- findMember
r2 <- addMember(r1Opt)
} yield r2
}
答案 1 :(得分:0)
当查询跨越两个表时,在Slick 3.0中简化嵌套db.runs的另一种方法是将查询连接到单个查询中。 Joining and Zipping。但是,OP似乎在同一个表上有一些不太常见的嵌套查询,所以这种方法在特定情况下可能没有用。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="300dp"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.7">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="A"
android:id="@+id/textView2"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="AAA"
android:id="@+id/textView4"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="AAAAA"
android:id="@+id/textView5"/>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.3">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="B"
android:id="@+id/textView3"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="BBB"
android:id="@+id/textView6"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="BBBB"
android:id="@+id/textView7"/>
</LinearLayout>
</LinearLayout>