从JSON字段

时间:2018-12-07 11:33:00

标签: php json symfony orm doctrine

我有2个实体:

class Opponent
{
  ...
  ...
  ...
}

class Process 
{

    /**
     * @var array
     * 
     * @ORM\Column(name="answers_in_related_questionnaires", type="json", nullable=true)
     */
    private $answersInRelatedQuestionnaires = [];

    .
    .        
    . 

}

在该领域中,我有对象对手的其他问题中的AnswersInRelatedQuestionnaires

"opponent": {
 "id":1088,
 "name":"Inora Life Versicherung"
}

我想在实体过程中编写一个吸气剂,它不仅要获取对手的值id和名称,还要获取整个实体对手。像这样:

private function getOpponent() : Opponent
{
    $id = $this->answersInRelatedQuestionnaires['opponent']['id'];
    return $entityManager->getRepository(Opponent::class)->find($id)
}

我已经读到,在实体中使用实体管理器不是一个好主意。有哪些针对我问题的解决方案?我可以在流程实体中使用流程存储库吗?

1 个答案:

答案 0 :(得分:1)

您不应在实体中注入实体管理器,这是非常糟糕的做法,并且违反了类之间关注点的分离。但是,如果您确实希望,确实可以在实体中注入实体管理器。

良好做法:

创建一个async void Select_Photos(object sender, System.EventArgs e) { try { var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Storage); if (status != PermissionStatus.Granted) { if (await CrossPermissions.Current.ShouldShowRequestPermissionRationaleAsync(Permission.Storage)) { await DisplayAlert("Need Storage", "Gunna need that Storage", "OK"); } var results = await CrossPermissions.Current.RequestPermissionsAsync(Permission.Storage); status = results[Permission.Storage]; } if (status == PermissionStatus.Granted) { await CrossMedia.Current.Initialize(); if (!CrossMedia.Current.IsPickPhotoSupported) { await DisplayAlert("no upload", "picking a photo is not supported", "ok"); return; } var file = await CrossMedia.Current.PickPhotoAsync(); if (file == null) return; img_selected.ImageSource = ImageSource.FromStream(file.GetStream); } else if (status != PermissionStatus.Unknown) { await DisplayAlert("Storage Permission Denied", "Can not continue, try again.", "OK"); } } catch { //... } } 类,并在其中包含与模型有关的所有功能。教义实体不是模型类。在Model/Process中,您可以注入实体管理器和所需的任何其他服务。

编辑:通过创建Model/Process类,我的意思是在Model/Process文件夹中Process目录内创建一个名为Model的类。您上课的路径将是:/src。当然,目录或类的名称可以是任何东西,但这是一个典型的约定。您的Model类应负责所有业务逻辑,例如模型的验证等。这确实会使您的代码结构更加复杂,但从长远来看,对于大型项目而言,这是一种滋味。您还需要一个/src/Model/Process才能在不同情况下正确填充流程模型(例如,从数据库,用户表单等加载时)。当然,最终,这只是在复杂性和可持续性之间进行权衡的问题。 / p>

here是关于Symfony模型的一种有趣的方法,主要适用于大型项目。

替代项:

如果仅在加载实体后访问Model/ProcessManager属性,则可以使用Doctrine PostLoad LifecycleCallback正确设置opponent属性。这不是一个坏习惯:

opponent

最后,如果您真的想将实体管理器注入到您的实体中,则可以通过自动装配通过依赖项注入来实现:

use Doctrine\Common\Persistence\Event\LifecycleEventArgs;

/**
 * @ORM\Entity()
 * @ORM\HasLifecycleCallbacks()
 */
class Product
{
    // ...
    private $opponentObject;

    /**
     * @ORM\PostLoad
     */
     public function onPostLoad(LifecycleEventArgs $args){
         $em = $args->getEntityManager();

         $id = $this->answersInRelatedQuestionnaires['opponent']['id'];
         $this->opponentObject = $em->getRepository(Opponent::class)->find($id);

     }

     public function getOpponent() {
         return $this->opponent;

     }
}