Doctrine “我怎么能?”;“德芳”;一个教义实体?

Doctrine “我怎么能?”;“德芳”;一个教义实体?,doctrine,doctrine-orm,Doctrine,Doctrine Orm,我想在我的代码中创建一个“类似API”的层,有效地隔离对更高级别代码的数据库访问。例如,我可能具有以下功能: class MyApi { private $my_user_id; function getContacts() { $contacts = $em->getRepository('Contacts')->findByOwner($this->my_user_id); $em->clear(); r

我想在我的代码中创建一个“类似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分离,这样我的视图就不会意外地修改托管实体。然而,当我想要比较两个连续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/>";
        }
    }
}
$my_contacts=$myapi->getContacts();
$my_groups=$myapi->getGroups();
foreach($my_group作为$group){
foreach($myu联系人作为$contact){
如果($group->getContacts()->包含($contact)){
echo“{$group->getName()}包含{$contact->getName()}!
”; }否则{ echo“{$group->getName()}不包含{$contact->getName()}!
”; } } }
但是,由于我在getContacts API调用结束时从EntityManager中分离了所有联系人,因此
$group->getContacts()
返回的对象与
$API->getContacts()
返回的对象是不同的PHP对象,因此
Contacts()
函数无法正常工作


在不放弃EntityManager提供的好处的情况下,我是否有任何选项可以“删除”我的实体,使它们成为有效的只读实体?(例如,表示同一数据库条目的所有托管实体都是同一个对象,在从API传回关联对象后,能够进一步水合关联对象等)

为什么您会担心视图会做出更改,并提交回数据库?如果您的视图不知道EM(它们也不应该知道),那么它们对实体所做的任何更改都将在请求结束时消失


我唯一能想到的另一个选择是,当结果注定要馈送到视图脚本时,将其作为数组进行水合。但是这样做会放弃很多方便的功能。

为什么您会担心您的视图将要进行的更改会提交回数据库?如果您的视图不知道EM(它们也不应该知道),那么它们对实体所做的任何更改都将在请求结束时消失


我唯一能想到的另一个选择是,当结果注定要馈送到视图脚本时,将其作为数组进行水合。但这样做会放弃很多方便的功能。

也许这有点晚了,但它对任何仍然需要回答这个问题的人都很有用

我认为这里缺少一个领域驱动的设计原则:。
在每个对象上,只能有两种方法:

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

getSomething() {
    //this kind of method NEVER changes internal state
}
记住适当的MVC,视图只需要get方法,它们永远不会改变任何东西。

如果只考虑CQS和MVC,则无需分离实体,也无需担心。

这可能有点晚了,但对于仍需要此问题答案的任何人来说,它都很有用

我认为这里缺少一个领域驱动的设计原则:。
在每个对象上,只能有两种方法:

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

getSomething() {
    //this kind of method NEVER changes internal state
}
记住适当的MVC,视图只需要get方法,它们永远不会改变任何东西。

如果只考虑CQS和MVC,则无需分离实体,也无需担心。

我不担心我的视图会自行刷新任何内容,但我担心控制器调用“getter”API操作,对返回的实体进行更改,然后调用涉及刷新EM的第二个API操作。第二个API调用将写入我的预期更改,以及在API调用之间进行的任何意外更改。我可以,只是小心不要在API之外进行更改,但API的目的是保护我自己不出错,并且使控制器不必担心实体与EM的关系。另一种选择是在将实体传递给视图之前分离实体。当然,您需要注意A)您已经获取了所有需要的关联,B)您的分离操作级联通过所有关联。我不担心我的视图会自行刷新任何内容,但我担心控制器调用“getter”API操作,对返回的实体进行更改,然后调用涉及刷新EM的第二个API操作。第二个API调用将写入我的预期更改,以及在API调用之间进行的任何意外更改。我可以,只是小心不要在API之外进行更改,但API的目的是保护我自己不出错,并且使控制器不必担心实体与EM的关系。另一种选择是在将实体传递给视图之前分离实体。当然,您需要注意A)您已经获取了所需的所有关联,B)您的分离操作级联了所有关联。