1

我有以下课程:

case class Product( title : String, description: String, contract: Contract)
case class Contract(contractType: ContractType, price: Int )
case class ContractType(description: String)

和这些 DTO:

case class ProductDto(id: Long, title: String, description: String, contractType: ContractTypeDto, price: Int)
case class ContractTypeDto(id: Long, description: String)

我需要创建一个方法来返回产品列表,但数据填充在 DTO 中,如下所示:

def list = Db.query[Product].fetch().toList.map(x => ProductDto(x.id, x.title, 
    x.description, ContractTypeDto(x.contract.contractType.id, 
    x.contract.contractType.description), x.contract.price))

问题是我无法访问 x.contract.contractType.id 但 SORM 允许我访问x.id(在第一级),有什么办法吗?

谢谢

4

1 回答 1

2

铸造方法

如果必须,您始终可以访问idusing 强制转换:

x.contract.contractType.asInstanceOf[ sorm.Persisted ].id

总方法

虽然使用模式匹配来产生一个完整的功能来做到这一点更干净:

def asPersisted[ A ]( a : A ) : Option[ A with sorm.Persisted ]
  = a match {
      case a : A with sorm.Persisted => Some( a )
      case _ => None
    }

然后我们可以像这样使用它:

asPersisted( x.contract.contractType ).map( _.id ) // produces Option[ Long ]

整体方法的好处是您可以保护自己免受运行时强制转换异常的影响,如果您尝试强制转换非持久值,就会出现这种情况。

拉皮条的总体方法

如果您不觉得这令人不安,您也可以将“皮条客”asPersisted作为使用值类的一种方法:Any

implicit class AnyAsPersisted[ A ]( val a : A ) extends AnyVal {
  def asPersisted : Option[ A with sorm.Persisted ]
    = a match {
        case a : A with sorm.Persisted => Some( a )
        case _ => None
      }
}

然后你就可以像这样使用它:

x.contract.contractType.asPersisted.map( _.id ) // produces Option[ Long ]
于 2013-05-28T18:47:02.480 回答