有人知道如何使用值对象(嵌入字段)查询数据库吗?
当尝试使用查询生成器获取记录计数时,我得到以下错误:
[Semantical Error] line 0, col 55 near 'email = :ema': Error: Class
Domain'User'Entity'User has no field or association named email
存储库方法为:
<?php
namespace AppBundle'Repository;
use Doctrine'ORM'EntityRepository;
use Domain'User'Entity'User;
use Domain'User'Exception'UserNotFoundException;
use Domain'User'Repository'UserRepository;
use Domain'User'ValueObject'Email;
use Domain'User'ValueObject'UserId;
class DoctrineUserRepository extends EntityRepository implements UserRepository
{
/** {@inheritdoc} */
public function isEmailUnique(Email $email)
{
$qb = $this->createQueryBuilder('u');
$count = (int) $qb
->select($qb->expr()->count('u'))
->where('u.email = :email')
->setParameter('email', $email->getValue())
->getQuery()
->getSingleScalarResult()
;
return 0 === $count;
}
}
映射工作(记录插入,数据库模式更新)
User
映射:
Domain'User'Entity'User:
type: entity
table: user
repositoryClass: AppBundle'Repository'DoctrineUserRepository
id:
id:
type: guid
generator:
strategy: NONE
embedded:
email:
class: Domain'User'ValueObject'Email
columnPrefix: false
fullName:
class: Domain'User'ValueObject'FullName
columnPrefix: false
password:
class: Domain'User'ValueObject'PasswordHash
columnPrefix: false
fields:
createdAt:
type: datetime
column: created_at
Email
值对象映射:
Domain'User'ValueObject'Email:
type: embeddable
fields:
value:
type: string
length: 255
unique: true
column: email
使用以下版本的库(composer show -i
):
doctrine/annotations v1.2.4
doctrine/cache v1.4.1
doctrine/collections v1.3.0
doctrine/common v2.5.0
doctrine/dbal v2.5.1
doctrine/doctrine-bundle v1.4.0
doctrine/doctrine-cache-bundle v1.0.1
doctrine/inflector v1.0.1
doctrine/instantiator 1.0.4
doctrine/lexer v1.0.1
doctrine/orm v2.5.0
symfony/symfony 2.7.x-dev 84ce2c5
用户实体:<?php
namespace Domain'User'Entity;
use Domain'User'Event'UserSignedUp;
use Domain'User'ValueObject'Email;
use Domain'User'ValueObject'FullName;
use Domain'User'ValueObject'PasswordHash;
use Domain'User'ValueObject'UserId;
use SimpleBus'Message'Recorder'ContainsRecordedMessages;
use SimpleBus'Message'Recorder'PrivateMessageRecorderCapabilities;
class User implements ContainsRecordedMessages
{
use PrivateMessageRecorderCapabilities;
/** @var UserId */
private $id;
/** @var Email */
private $email;
/** @var FullName */
private $fullName;
/** @var Password */
private $password;
/** @var 'DateTime */
private $createdAt;
public function __construct(UserId $id, Email $email, FullName $fullName, PasswordHash $password)
{
$this->id = $id;
$this->email = $email;
$this->fullName = $fullName;
$this->password = $password;
$this->createdAt = new 'DateTime();
$this->record(new UserSignedUp($this->id));
}
/** @return UserId */
public function getId()
{
return $this->id;
}
/** @return Email */
public function getEmail()
{
return $this->email;
}
/** @return FullName */
public function getFullName()
{
return $this->fullName;
}
/** @return Password */
public function getPassword()
{
return $this->password;
}
/** @return 'DateTime */
public function getCreatedAt()
{
return $this->createdAt;
}
}
Email值对象:
<?php
namespace Domain'User'ValueObject;
use Domain'Core'Validation'Assert;
final class Email
{
/** @var string */
private $value;
/** @param string $value */
public function __construct($value)
{
Assert::notEmpty($value);
Assert::email($value);
$this->value = $value;
}
/** @return string */
public function getValue()
{
return $this->value;
}
}
我认为目前还不完全支持按属性比较值对象,这就是为什么必须指定要针对哪个字段的原因。
试着这样写查询,然后试一下:
$qb
->select($qb->expr()->count('u'))
->where('u.email.value = :email')
->setParameter('email', $email->getValue())
->getQuery()
->getSingleScalarResult()
;
注意u.email.value