2015-07-17 8 views
10

Jestem nowicjuszem w Slick 3 i do tej pory zrozumiałem, że db.run to wywołanie asynchroniczne. Mapa .map lub .flatMap jest uruchamiana po zwróceniu Przyszłości.SLICK 3.0 - wiele zapytań zależnych od siebie - db.run (akcja)

Problem w poniższym kodzie polega na tym, że wszystkie zapytania podrzędne nie działają (zagnieżdżone db.run).

Pojęciowo mówiąc, czego nie dostaję? Czy prawidłowe jest wykonywanie tego rodzaju kodu, jak poniżej? zasadniczo w .map pierwszego zapytania wykonuję pewne czynności w zależności od pierwszego zapytania.

Widzę wszędzie dla pętli z zyskiem, czy to jedyny sposób, aby przejść? Czy problem w moim kodzie jest związany z zwróconą wartością Future?

val enterprises = TableQuery[Enterprise] 
val salaries = TableQuery[Salary] 

//Check if entered enterprise exists 
val enterpriseQS = enterprises.filter(p => p.name.toUpperCase.trim === salaryItem.enterpriseName.toUpperCase.trim).result 

val result=db.run(enterpriseQS.headOption).map(_ match 
{ 
    case Some(n) => { 
     //if an enterprise exists use the ID from enterprise (n.id) when adding a record to salary table 
     val addSalary1 = salaries += new SalaryRow(0, n.id, salaryItem.worker) 
     db.run(addSalary1) 
    } 
    case None => { 
     //if an enterprise with salaryItem.enterpriseName doesn't exist, a new enterprise is inserted in DB 
     val enterpriseId = (enterprises returning enterprises.map(_.id)) += EnterpriseRow(0, salaryItem.enterpriseName) 
     db.run(enterpriseId).map{ 
      e => { 
       val salaryAdd2 = salaries += new SalaryRow(0, e, salaryItem.worker) 
       db.run(salaryAdd2) 
      } 
     } 
    } 
}) 
+0

Hi @ user1237981 zrobił odpowiedź poniżej pomoc? A może było to niejasne? A może brakowało mi tego, czego potrzebujesz? –

+0

Dziękuję RIchard, zadziałało od razu. Byłem na wakacjach i nie mogłem odpowiedzieć od razu. – user1237981

+0

Świetnie! Dziękuję Ci. –

Odpowiedz

12

Problem w moim kodu poniżej jest to, że wszystkie zapytania podrzędne nie działają (zagnieżdżony db.run)

Podejrzewam jesteś kończąc zagnieżdżonych Future[R] wyników. Nie zbadałem tego jednak. Ponieważ ...

Pojęciowo, czego nie dostaję?

Sposób, w jaki radzę sobie z tym, to spojrzenie na łączenie DBIO[R]. To może być koncepcja, która pomaga.

Co robisz, próbujesz uruchomić każdą akcję indywidualnie ( (zapytanie, wstaw ...). Zamiast tego połącz poszczególne działania w jedną akcję i uruchom je.

bym ponownie napisać główną logikę jak to:

val action: DBIO[Int] = for { 
    existingEnterprise <- enterpriseQS.headOption 
    rowsAffected  <- existingEnterprise match { 
     case Some(n) => salaries += new SalaryRow(0, n.id, salaryItem.worker) 
     case None => createNewEnterprise(salaryItem) 
    } 
    } yield rowsAffected 

dla przypadku None bym utworzyć metody pomocnika:

def createNewEnterprise(salaryItem: SalaryItem): DBIO[Int] = for { 
    eId   <- (enterprises returning enterprises.map(_.id)) += EnterpriseRow(0, salaryItem.enterpriseName) 
    rowsAffected <- salaries += new SalaryRow(0, eId, salaryItem.worker) 
    } yield rowsAffected 

Wreszcie możemy uruchomić że:

val future: Future[Int] = db.run(action) 
    // or db.run(action.transactionally)  

    val result = Await.result(future, 2 seconds) 

    println(s"Result of action is: $result") 

Druga połowa numeru blog post I've written mówi o tym więcej.

Kod Użyłem jest: https://github.com/d6y/so-31471590

+0

Witaj Richard, dziękuję za odpowiedź. Wszystko działało dobrze. Po prostu muszę ćwiczyć z tymi dla pętli. Poza tym zajrzałem do twojego bloga i zacząłem się inspirować. Bardzo dobrze zrobione. Dzięki jeszcze raz. – user1237981

Powiązane problemy