2014-11-29 2 views
7

у меня есть эти тематические классы:Определение проекции для сопоставления вложенных классов случае

case class PolicyHolder(id : String, firstName : String, lastName : String) 
case class Policy(address : Future[Address], policyHolder : Future[PolicyHolder], created : RichDateTime, duration : RichDuration) 

то у меня есть пятно схемы, определенной для политики

class PolicyDAO(tag: Tag) extends Table[Policy](tag, "POLICIES") with DbConfig { 
    def address = column[String]("ADDRESS", O.PrimaryKey) 
    def policyHolder = foreignKey("POLICY_HOLDER_FK", address, TableQuery[PolicyHolderDAO])(_.id) 

    def created = column[RichDateTime]("CREATED") 
    def duration = column[String]("DURATION") 

    def * = (address, policyHolder, created, duration) <> (Policy.apply, Policy.unapply) 
} 

Что это лучший способ для меня, чтобы определить это правильно отобразить поле policyHolder внутри моего класса Policy от значения внешнего ключа до фактического экземпляра класса case PolicyHolder.

ответ

3

Наше решение этой проблемы состоит в том, чтобы поместить идентификатор внешнего ключа в класс case, а затем использовать ленивый val или def (последний может быть защищен кешем) для извлечения записи с помощью ключа. Это предполагает, что ваши PolicyHolder s хранятся в отдельной таблице - если они денормализованы, но вы хотите рассматривать их как отдельные классы case, тогда у вас может быть lazy val/def в Policy построить новый класс case вместо получения записи используя внешний ключ.

class PolicyDAO(tag: Tag) extends Table[Policy](tag, "POLICIES") with DbConfig { 
    def address = column[String]("ADDRESS", O.PrimaryKey) 
    def policyHolderId = column[String]("POLICY_HOLDER_ID") 

    def created = column[RichDateTime]("CREATED") 
    def duration = column[String]("DURATION") 

    def * = (address, policyHolderId, created, duration) <> (Policy.apply, Policy.unapply) 
} 

case class Policy(address : Future[Address], policyHolderId : Future[String], created : RichDateTime, duration : RichDuration) { 
    lazy val policyHolder = policyHolderId.map(id => PolicyHolderDAO.get(id)) 
} 

Мы также использовали общий набор создания/обновления/удаления методов для учета вложенности, так что, когда Policy совершается его внутренняя PolicyHolder также будет совершено; мы использовали класс CommonDAO, который расширил Table и имел прототипы для методов create/update/delete, а затем все DAO расширили CommonDAO вместо Table и заново создали/обновили/удалили по мере необходимости.


Edit: Для того, чтобы сократить ошибки и уменьшить количество шаблонного, мы должны были написать, мы использовали code generation tool Slick в - таким образом операции CRUD может быть автоматически генерируется из схемы

Смежные вопросы