我怎样才能“诽谤”一个Doctrine2实体?

时间:2011-08-10 19:25:10

标签: doctrine doctrine-orm

我想在我的代码中创建一个“类似API”的层,有效地阻止数据库访问更高级别的代码。例如,我可能有以下功能:

class MyApi {
    private $my_user_id;
    function getContacts() {
        $contacts = $em->getRepository('Contacts')->findByOwner($this->my_user_id);
        $em->clear();
        return $contacts;
    }
    function getGroups() {
        $groups = $em->getRepository('Groups')->findByOwner($this->my_user_id);
        //hydrate each group's contacts list
        foreach ($groups as $group) {
            $group->getContacts();
        }
        $em->clear();
        return $groups;
    }
}

我正在使用$ em-> clear()在返回EntityManger之前从EntityManger中分离实体,因此我的视图不会意外地修改托管实体。但是,当我想比较两个顺序API函数返回的实体时,我遇到了问题。理想情况下,我希望视图/控制器包含:

$my_contacts = $myapi->getContacts();
$my_groups = $myapi->getGroups();

foreach($my_groups as $group) {
    foreach ($my_contacts as $contact) {
        if ($group->getContacts()->contains($contact)) {
            echo "{$group->getName()} contains {$contact->getName()}!<br/>";
        } else {
            echo "{$group->getName()} does not contain {$contact->getName()}!<br/>";
        }
    }
}

但是,由于我在getContacts API调用结束时从EntityManager中分离了所有联系人,因此$group->getContacts()返回的对象与<{>返回的对象不同的 PHP对象。 1}},因此$api->getContacts()函数无法正常工作。

我是否有任何“defanging”我的实体的选项,使它们有效地只读,而不会放弃EntityManager提供的好处? (例如,表示相同数据库条目的所有托管实体都是同一个对象,能够在从API传回相关对象后进一步保持水合等)。

2 个答案:

答案 0 :(得分:1)

为什么您会担心您的视图会进行更改以提交回数据库?如果您的观点不了解EM(并且他们不应该),那么他们对实体所做的任何更改都将在请求结束时消失。

我能想到的唯一另一个选择是将结果保存为数组,当它们注定要被提供给视图脚本时。但这放弃了许多方便的功能。

答案 1 :(得分:0)

也许这有点晚了,但是对于那些仍然需要在这个问题上回答的人来说这很有用......

我认为这里缺少一个领域驱动设计原则:Command Query Separation 在每个对象上,您只能使用两种方法:

doSomething() {
    //this kind of method can change the internal state
}

getSomething() {
    //this kind of method NEVER changes internal state
}

牢记适当的MVC,观点应该只需要get-methods,它们永远不会改变一个东西 如果仅考虑CQS和MVC,则不必分离您的实体,也不需要担心。