Переходный эквивалент в слике

1

Я использую Slick для отображения класса case для таблиц. В определенных классах классов мне нужно иметь дополнительное поле, которого нет в таблице базы данных. Это значение поля будет обновляться на основе некоторых условий ведения бизнеса. Однако я не могу этого сделать, поскольку класс case и slick table должны иметь одинаковые поля.

В java с Hibernate это же было достигнуто с @Transient аннотации @Transient. Как я могу решить эту проблему? Я связал, добавив @transient аннотацию в поле класса case. Но на графическом изображении отображаются ошибки компиляции.

Теги:
case-class
slick
transient

4 ответа

4

Как насчет этого?

case class Container(name: String, width: Float, height: Float, isApproved: Boolean)

val c: Container = ...
val approvedContainer = c.copy(isApproved=true)

И в Slick

...
def * = (name, width, height, false) <> (Container.tupled, Container.unapply)
...

Я не пробовал это, и есть вероятность, что вы столкнетесь с проблемами вставки с вышеуказанным, с которыми вы можете работать или нет.

Другой способ сделать это:

case class Container(name: String, width: Float, height: Float)(val isApproved: Boolean)
object Container{
  def applyFunction = (Container.apply _).tupled
  def approve(c: Container) = applyFunction(Container.unapply(c).get)(true)
  def createNonApproved = (t: (String, Float, Float)) => applyFunction(t)(false)
}

И в Slick

...
def * = (name, width, height, false) <> (Container.createNonApproved, Container.unapply)
...

Имейте в виду, что равенство классов case сравнивает только первый список аргументов.

scala> Container("foo",1,2)()
res2: Container = Container(foo,1.0,2.0)

scala> Container.approve(res2)
res3: Container = Container(foo,1.0,2.0)

scala> res2 == res3
res4: Boolean = true

scala> res2.isApproved
res5: Boolean = false

scala> res3.isApproved
res6: Boolean = true

Имейте в виду https://issues.scala-lang.org/browse/SI-3664

  • 0
    Мне нужно было быстрое решение проблемы. Я надеюсь, что ваш ответ работает. Я попробую решение, как вы предложили. Спасибо за подробный ответ. Ценить это. :)
1

Иметь ту же проблему, решаемую с помощью этого кода:

case class Container(name: String, width: Float, height: Float, isApproved: Boolean)

class Containers(tag: Tag) extends Table[Container](tag, "CONTAINERS") {

  def name = column[String]("NAME", O.PrimaryKey)
  def width = column[Float]("WIDTH")
  def height = column[Float]("HEIGHT")

  def create = (name: String, width: Float, height: Float) =>
    Container(name, width, height, isApproved = false)

  def destroy(container: Container) =
    Some((container.name, container.width, container.height))

  def * = (name, width, height) <> (create.tupled, destroy)
}
1

Вы пробовали это?

case class Container(name: String, width: Float, height: Float, condition: Boolean)

class Containers(tag: Tag) extends Table[Container](tag, "CONTAINERS") {
  def name = column[String]("NAME", O.PrimaryKey)
  def width = column[Float]("WIDTH")
  def height = column[Float]("HEIGHT")

  def applyBusinessCondition(): Boolean = ...

  def * = (name, width, height, applyBusinessCondition()) <> (Container.tupled, Container.unapply)
}

Я думаю, вы могли бы использовать функцию внутри или вне класса Containers и называть ее в * проекции таблицы. Вы также можете установить условие False внутри определения таблицы и впоследствии изменить его.

  • 0
    Спасибо за помощь. Но я не пробовал это. Я решил это по-другому.
0

Я не пробовал решение @jvican. Я попробую это. Но я решил это по-другому, не изменяя поля классов case и slick mapping tables.

Я создал признак

trait Approvable[TId <:AnyVal]{
  var isApproved: Boolean = false
}

Затем я смешал класс в своем классе с Approvable признаком. После проверки состояния бизнеса я обновляю поле isApproved с истинным/ложным.

  • 0
    Члены var делают вашу программу труднее понять и легче ошибиться (то есть иметь ошибку). Смотри мой ответ.
  • 0
    Да, я знал, что использование var может создать проблемы, так как это делает переменную изменчивой. Но мне срочно нужно было исправить это.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню