E1.04 Php Symfony Doctrine. Two groups of entities. (Wpf, Xamarin, Angular SPA, Reactjs SPA) - chempkovsky/CS2WPF-and-CS2XAMARIN GitHub Wiki

Here is how to work around the "flat data"-issues shown in two articles below:

We generate two groups of entities:

  • The first group of entities is used only for deployment the storages (only for creating tables in the database). This group of entities never used for select/insert/update/delete operations. So the developer can remove them from project.
    • it includes "*Entity.php"-files
  • The second group of entities is used for select/insert/update/delete operations. This group is devided into two subgroups:
    • Subgroup of entities for insert/update/delete operations
      • it includes "*EntityUpd.php"-files
    • Subgroup of entities for select operations
      • it includes "*EntitySel.php" and "*EntityTotal.php"-files

The entities of the first group have only scalar and object fields. The object field is declared for each foreign key of the database table.

The entities of the second group have only scalar fields even if database table has foreign key.

For instance, for aspnetrolemaskView the developer generates the following files

  • aspnetrolemaskViewEntityUpd.php
  • aspnetrolemaskViewEntitySel.php
  • aspnetrolemaskViewEntityTotal.php

For each viewModel the developer generates "*Page.php"-file. This class is used for pagination purpose.

"*EntitySel.php"-classes are used to send/receive data to/from the client app. So each field of such a classes has @SerializedName and @Assert attributes for json serialization and validation purposes.

We use NativeQuery along with "*EntitySel.php"-class for select operations

Here is "select" example

...

        $rsm = new ResultSetMapping($this->getDoctrine()->getManager());
        $rsm->addEntityResult(LitGenreViewEntitySel::class, "er");
        $rsm->addFieldResult("er", "GenreId", "genreid");
        $rsm->addFieldResult("er", "GenreName", "genrename");
        $offset = ($currentPage - 1) * $currentPageSize;
        $query = $this->getDoctrine()->getManager()->createNativeQuery("select t0000.GenreId as GenreId, t0000.GenreName as GenreName  from litgenres as t0000".$whereClause.$orderby." LIMIT " . $offset . "," . $currentPageSize, $rsm);
        foreach ($filters as $k => $v) {
            $query->setParameter($k, $v);
        }
        unset($k);unset($v);
...

We use Entity Manager along with "*EntityUpd.php"-class for insert/update/delete operation

Here is "insert" example

...

        $entityNew = new LitGenreViewEntityUpd();
        $entityNew->setGenreid($viewToAdd->getGenreid());
        $entityNew->setGenrename($viewToAdd->getGenrename());
        $this->getDoctrine()->getManager()->persist($entityNew);
        $this->getDoctrine()->getManager()->flush();
...

Here is "Update" example

...

        $rsm = new ResultSetMapping($this->getDoctrine()->getManager());
        $rsm->addEntityResult(LitGenreViewEntityUpd::class, "er");
        $rsm->addFieldResult("er", "genreid", "genreid");
        $rsm->addFieldResult("er", "genrename", "genrename");
        $query = $this->getDoctrine()->getManager()->createNativeQuery("select t0000.GenreId as genreid, t0000.GenreName as genrename  from litgenres t0000".$whereClause, $rsm);
        if(!is_null($GenreId)) { $query->setParameter("GenreId", $GenreId); }
        $rsltEx = $query->getResult();
        if (!$rsltEx) {
            throw $this->createNotFoundException(); // error 404
        }
        if(count($rsltEx) != 1) {
            throw $this->createNotFoundException(); // error 404
        }
        $rsltEx[0]->setGenrename($viewToUpdate->getGenrename());
        $this->getDoctrine()->getManager()->flush();

...

Here is "Delete" example

...

        $rsm = new ResultSetMapping($this->getDoctrine()->getManager());
        $rsm->addEntityResult(LitGenreViewEntityUpd::class, "er");
        $rsm->addFieldResult("er", "genreid", "genreid");
        $rsm->addFieldResult("er", "genrename", "genrename");
        $query = $this->getDoctrine()->getManager()->createNativeQuery("select t0000.GenreId as genreid, t0000.GenreName as genrename  from litgenres t0000".$whereClause, $rsm);
        if(!is_null($GenreId)) { $query->setParameter("GenreId", $GenreId); }
        $rsltEx = $query->getResult();
        if (!$rsltEx) {
            throw $this->createNotFoundException(); // error 404
        }
        if(count($rsltEx) != 1) {
            throw $this->createNotFoundException(); // error 404
        }
        $this->getDoctrine()->getManager()->remove($rsltEx[0]);
        $this->getDoctrine()->getManager()->flush();

...