如何使用sorm中的原始实体id创建不同的实体类型?

时间:2013-05-28 17:27:05

标签: scala sorm

我有以下课程:

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(在第一级),有什么方法可以做到吗?

由于

1 个答案:

答案 0 :(得分:2)

施法方法

如果您必须:

,您始终可以使用演员来访问id
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作为方法“pimp”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 ]