Ich bin ziemlich neu in der Scala-Programmierung. Neben Scala habe ich nie funktionale Programmierung gelernt. Mit dem gesagt, ich versuche derzeit, einen guten Weg zu finden, um Eigenschaften, Klassen, usw. auf einem Projekt zu definieren, das glatt verwendet.Generischen TableQuery-Typ für Elterneigenschaft verwenden
Meine Idee war, eine Eigenschaft zu haben, die die Methoden hat, die auf den Kindklassen implementiert werden, und einige würden auf der Elternklasse selbst implementiert werden. Ich habe einen Weg gefunden, der funktioniert, aber ich habe keine Ahnung warum. Ich bin mir nicht sicher, ob dieses Problem damit zusammenhängt, wie Slick oder Scala funktioniert.
ich wie eine Konstruktion wurde mit:
trait CompanyDAO extends BaseDao[Company]{
self: DBProfile =>
Aber den folgenden Typenkonflikt Fehler geben:
[error] found : slick.lifted.TableQuery[CompanyDAO.this.CompanyTable] [error] required: slick.lifted.TableQuery[CompanyDAO.this.profile.api.Table[Company]] [error] (which expands to) slick.lifted.TableQuery[CompanyDAO.this.profile.Table[Company]] [error] Note: CompanyDAO.this.CompanyTable <: CompanyDAO.this.profile.api.Table[Company], but class TableQuery is invariant in type E. [error] You may wish to define E as +E instead. (SLS 4.5) [error] override def toTable = TableQuery[CompanyTable]
Aber wenn ich
verwendenself: DBProfile with BaseDao[Company] =>
Dann wird die Zusammenstellung Werke (BTW, bekam die Lösung von another post)
Also, meine Fragen:
1) Warum Totable Zuordnung Werke Selbsttypen verwenden, während das Merkmal erstreckt nicht? Wie interpretiert scala den Typ von toTable in beiden Szenarien?
2) Gibt es eine Möglichkeit, das "Merkmal CompanyDAO extends BaseDao" anzupassen, um den Fehler zu beheben?
Vielen Dank im Voraus.
import scala.concurrent.Future
import slick.basic.DatabaseConfig
import slick.jdbc.JdbcProfile
trait DBConfiguration {
lazy val config = DatabaseConfig.forConfig[JdbcProfile]("mytrade")
}
trait DBProfile {
val config: DatabaseConfig[JdbcProfile]
val db: JdbcProfile#Backend#Database = config.db
val profile : JdbcProfile = config.profile
}
trait BaseDao[T <: Any] {
self: DBProfile =>
import profile.api._
import slick.lifted.TableQuery
def toTable():TableQuery[Table[T]]
def findAll():Future[Seq[T]] = db.run(toTable.result)
}
case class Company(name: String, code: Int)
// If I use the construction like the comment below, it will fail
//trait CompanyDAO extends BaseDao[Company]{
//self: DBProfile =>
trait CompanyDAO {
self: DBProfile with BaseDao[Company] =>
//import from DBProfile trait
import profile.api._
class CompanyTable(tag: Tag) extends Table[Company](tag, "COMPANY") {
import slick.ast.BaseTypedType
import slick.jdbc.JdbcType
def name = column[String]("name")
def code = column[Int]("code")
def * = (name, code) <> (Company.tupled, Company.unapply)
}
override def toTable = TableQuery[CompanyTable]
}
EDIT: einige andere Dinge, die ich versucht haben
BaseDao erweitern, wenn ich die Erklärung von Totable ändern:
def toTable[S <: TableQuery[Table[_]]]():S
Die Typenkonflikt geht weg, aber ich erhalte jetzt :
test.scala:27: dead code following this construct [error] def findAll():Future[Seq[T]] = db.run(toTable.result)
Versucht auch mit Selbst-Typ a Und es gab mir den gleichen Fehler.
1) https: // stackoverflow.com/questions/2224932/Differenz-zwischen-Merkmal-Vererbung-und-Selbst-Typ-Annotation 2) https://stackoverflow.com/questions/1990948/what-is-the-difference-between-self-types- and-trait-subclasses 3) https://softwareengineering.stackexchange.com/questions/219038/what-is-the-difference-between-self-types-and-trait-inheritance-in-scala –