2016-04-05 12 views
0

Geçerli soru next one ile ilişkilidir, ancak şimdi veriyi veritabanına eklemek yerine eklemek gerekiyor.slick 3 iki leftJoin sorgu sonucu eşleme sınıfları

Önümüzdeki üç vaka sınıfları:

case class A (id: Long, bList: List[B]) 
case class B (id: Long, aId: cList: List[C]) 
case class C (id: Long, bId: Long) 

Ve iki leftJoin fonksiyonları ile sorgu ve filtreleme atable sonuçlar için incomingAId:

val query = (for { 
    ((aResult,bResult),cResult) <- aTable.filter(_.id === incomigAId) 
     .joinLeft(bTable).on(_.id === _.aId) 
     .joinLeft(cTable).on(_._2.map(_.id) === _.bId) 
    } yield ((aResult,bResult),cResult)).result.transactionally 

Sonraki sorgu çalışır ve sonuç geçerli görünüyor ama değil mi' Bunu vaka sınıflarına göre işlemek kolaydır. Ayrıca, executionResultSeq[Nothing] türü vardır ve haritalama işlemi böyle bir şeyi gerektirir:

database.run(query).map{ executionResult => 
    executionResult.map { vectorElement: [Tuple2[Tuple2[A, Option[B]], Option[C]]] 
    ... 
    } 
} 

Seq [Hiçbir şey] (sorguda değişiklikleri) engellemek için herhangi bir uygun yolu var mı? Ya da sorgu sonucu türü iyi ise, lütfen yukarıdaki vaka sınıflarına nasıl eşleştirileceğini nasıl çözebilir misiniz?

cevap

0

Şu anda bir sonraki çözümü kullanıyorum, ancak kodun bir kısmının optimize edilebileceğini varsayalım (örneğin, başka bir şeyle değiştirerek groupBy).

 execute(query).mapTo[Vector[((A, Option[B]), Option[C])]] 
     .flatMap { insideFuture => 
      insideFuture.groupBy(_._1._1).mapValues { values => 
      //scala groupBy losts ordering 
      val orderedB = values.groupBy(_._1._2).toSeq.sortBy(_._1.map(_.id)).toMap 
      orderedB.mapValues(_.map(_._2)) 
      }.headOption match { 
      case Some(data) => Future.successful { 

       data._1.copy(bList = data._2.map { 
       case (Some(bElement), optionCElements) => 
        bElement.copy(cList = optionCElements.toList.flatten) 

       case _ => 
        throw new Exception("Invalid query result. Unable to find B elements") 
       }.toList) 
      } 
      case None => Future.failed(new Exception("Unable to find A with next id " + incomigAId)) 
      } 
     } 
    }