一个学说实体能自我解读吗


Can a Doctrine entity read itself?

只是好奇。。我有一些这样的代码:

//$em is EntityManager of Doctrine
//$className is a type that uses polymorphism (subtype of a parent type)
$pricing = $em->getRepository($className)->findOneBy(array(
    'active' => true,
    'product_id' => (int) $this->id
));
//gets serialization of certain variables of $className
return $pricing->getSerialization();

但是。。。与其在$className的外部调用findOneBy,我可以在Entity(即$className)内部移动getSerialization()方法,并从那里返回类参数吗?

我想这是不可能的,因为实体无法读取自己。对的

我试图解决的问题是……在上面的例子中,实体是通过条令填充的,然后它返回数据。因此我必须使用另一个类来填充实体。如果没有条令,我知道可以做一些事情,比如从实体内部读取数据,即通过mysqli,然后直接或通过方法返回属性。换句话说,我是否绝对需要另一个位置(Entity之外的类/函数/方法)来填充实体?

样本实体看起来像

class Pricing
{
    function getSerialization(){}
    /**
     * @var integer @Column(name="id", type="integer", nullable=false)
     *      @Id
     *      @GeneratedValue(strategy="IDENTITY")
     */
    protected $id;
    //etc, a typical Doctrine Entity
}

是的,实体类的实例可以读取自身
但我想你的问题应该是:;条令实体可以加载和读取自己吗"。答案是否定的…

实体的装载由条令内部管理。如果希望实体类自行加载,则意味着向实体类中注入EntityManager

这是个坏主意,我引用@BryanM的话。他对另一个堆栈溢出问题的回答很好地涵盖了这一点:

允许实体对象依赖实体管理器不是一个好主意。它将实体与持久层联系起来,这是条令2专门试图解决的问题。依赖实体管理器的最大麻烦是,它使您的模型很难在远离数据库的情况下进行隔离测试。

您可能应该依赖服务对象来处理依赖实体管理器的操作。

这意味着您需要负责从外部加载实体。我仍然看不出getSerialization有什么问题。它可以在Entity类中,并且可以在实体加载后使用,对吗?

如果您想同时进行加载和序列化,我建议制作一个PricingService,在其中注入存储库或实体管理器,并定义一个完成所有这些的公共方法。例如:

<?php
use Application'Entity'Pricing;
use Doctrine'ORM'EntityManager;
use Doctrine'ORM'EntityRepository;
class PricingService
{
    /**
     * @var EntityManager
     */
    protected $entityManager;
    /**
     * @param EntityManager $entityManager
     */
    public function __construct(EntityManager $entityManager)
    {
        $this->entityManager = $entityManager;
    }
    
    /**
     * @return EntityRepository;
     */
    protected function getRepository()
    {
        return $this->entityManager->getRepository(`Application'Entity'Pricing`);
    }
    /**
     * @param $params
     * @return array 
     */
    public function findSerializedBy($params)
    {
        $pricing = $this->getRepository()->findOneBy($params);
        return $pricing->getSerialization();
    }
}

现在您可以直接使用您的奖励服务:

$serializedPricing = $pricingService->findSerializedBy(array(
    'active' => true,
    'product_id' => (int) $this->id
));

当然,您可以通过使用$classname添加另一个参数来概括您的服务。