加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

为什么Scala不能找到参数scala.slick.session.Session的隐含值?

发布时间:2020-12-16 18:51:55 所属栏目:安全 来源:网络整理
导读:我正在使用Slick 1.0.1运行 Scala Play 2.2应用程序.我试图将所有数据库调用包装到将来的尝试中,例如: object DbTeachers extends Table[DbTeacher]("edu_teachers") {... def insertTeacher(school: Int,userId: String) (implicit ec: ExecutionContext,d
我正在使用Slick 1.0.1运行 Scala Play 2.2应用程序.我试图将所有数据库调用包装到将来的尝试中,例如:

object DbTeachers extends Table[DbTeacher]("edu_teachers") {
...
  def insertTeacher(school: Int,userId: String)
                   (implicit ec: ExecutionContext,db: Database) = 
    future { Try { db.withSession => { implicit s: Session =>
      (DbTeachers.school ~ DbTeachers.teacher).insert(school,userId)
  }}}
}

我发现模式未来{Try {db.withSession => {ACTUAL_CODE_GOES_HERE}}}会产生混乱,我想将其抽象如下:

sealed class DbAsync[T](block: => T) {
  import play.api.libs.concurrent.Execution.Implicits.defaultContext
  implicit lazy val db = Database.forDataSource(DB.getDataSource())
  def get: Future[Try[T]] = future { Try { db.withSession { implicit s: Session =>
    block 
  }}}
}

object DbAsync {
  def apply[T](block: => T): Future[Try[T]] = new DbAsync[T](block).get
}

然后我可以将insertTeacher函数编写为:

def insertTeacher(school: Int,userId: String) = DbAsync {
  (DbTeachers.school ~ DbTeachers.teacher).insert(school,userId)
}

但是,scala编译器(2.10.2)抱怨这个:找不到参数会话的隐式值:scala.slick.session.Session

根据我的理解,insert()方法在DbAsync块中的范围内确实有一个隐式会话变量,并且因为它是一个按名称调用的参数,所以在DbAsync中调用它之前,它不应该被实际评估,此时在范围内会有一个隐式会话对象.

所以,我的问题是,如何说服Scala编译器在范围内实际存在隐式Session对象?

解决方法

你的建议不正确.在哪里评估call-by-name参数并不重要.所有隐式参数都应在编译时在需要它们的地方解析.

你可以这样工作:

def dbAsync[T](block: Session => T): Future[Try[T]] = {
  import play.api.libs.concurrent.Execution.Implicits.defaultContext
  implicit lazy val db = Database.forDataSource(DB.getDataSource())
  future { Try { db.withSession { block }}}
}

def insertTeacher(school: Int,userId: String) = dbAsync { implicit s: Session =>
  (DbTeachers.school ~ DbTeachers.teacher).insert(school,userId)
}

请注意,您不需要类DbAsync也不需要对象DbAsync.

请注意,不应使用defaultContext进行阻止操作.您可以使用配置的线程池创建其他ExecutionContext.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读