2013-07-16 10 views
7

Mam problem podczas usuwania czegoś z dysku BD.

Problem polega na tym, że nie tylko kasuje obiekt, którego szukałem (używając findOneBy), ale wszystkie obiekty związane z głównym identyfikatorem.

// --- Controller

$new = $this->getDoctrine()->getManager(); 
$OBJcar = $new->getRepository('SomeOtherBundle:CarEntityClass') 
    ->findOneBy(array('idOwner' => $idowner, 'idCar' => $idcar)); 
if($OBJcar){ 
    $new->remove($OBJcar); 
    $new->flush(); 
    $msj="The car for an specific owner has been erased."; 
} 

// --- Profiler (Query)

"START TRANSACTION" 
    Parameters: { } 
    Time: 0.22 ms 
DELETE FROM schema.CarTable WHERE id_owner = ? 
    Parameters: ['123456'] 
    Time: 0.63 ms 
"COMMIT" 
    Parameters: { } 
    Time: 0.63 ms 

Jak usunąć jeden wiersz Dostaję od db?

+2

Wszystko wygląda poprawnie .. Nie używasz przypadkowo "kaskadowego usuwania" lub "kaskadowania wszystkiego" w dowolnych konfiguracjach, prawda? –

+0

Mam złożony klucz podstawowy na stole. Stosunki wyglądać następująco: CREATE TABLE schema.car ( id_car bigint NOT NULL, id_owner bigint NOT NULL, CONSTRAINT car_pkey PRIMARY KEY (id_car, id_owner) CONSTRAINT car_person_fk FOREIGN KEY (id_owner) REFERENCJE schema.persons (id) odpowiadają PROSTY Aktualizacja na żadne działanie USUŃ żadnego działania, CONSTRAINT car_type_fk KLUCZ obcych (id_car) ODNOŚNIKI schema.cartype (id) odpowiadają PROSTY Aktualizacja na CASCADE Przy usuwaniu CASCADE ); –

Odpowiedz

4

Zastosowanie DQL

$query = $em->createQuery('DELETE SomeOtherBundle:CarEntityClass c WHERE c.idOwner = 4 AND c.id = 10'); 
$query->execute(); 

To usunie tylko jeden samochód z ID 10 i właściciela o identyfikatorze 4.

+0

Idealne, dzięki! –

23

głosowałem dół odpowiedź wyżej, bo jestem zmęczony osób korzystających DQLs ciągów. Nie jest on zinstrumentalizowany, nie zorientowany na obiekt (nawet jeśli w tle działa dql z obiektami), nie korzysta z mechanizmów buforujących, które zapewnia budowniczy kwerend, jest nieelastyczny i po prostu wygląda na nieczysty.

Oto „właściwy sposób” (IMHO):

  1. dodać repozytorium klasy dla podmiotu
  2. dodać metodę trzeba z konstruktora zapytań w nim
  3. wywołać metodę podczas przekazywania parametrów potrzebnych do specyficznych repozytorium obiektowe ACTION
  4. dostać łatwym w obsłudze Wynik

oto t on code:

namespace ProjectName\BundleName\Repository; 
use Doctrine\ORM\EntityRepository; 

class CarRepository extends EntityRepository 
{ 
    public function deleteCarWithOwner($ownerId,$carId) 
    { 
     $isDeleted = $this->createQueryBuilder("car") 
      ->delete() 
      ->where('car.id = :id')->setParameter("id", $id) 
      ->andWhere('car.idOwner = :owner')->setParameter("owner", $ownerId) 
      ->getQuery()->execute(); 

     return $isDeleted; 
    } 
} 

Zobacz także http://doctrine-orm.readthedocs.org/en/latest/reference/query-builder.html, aby uzyskać informacje na temat konstruktora zapytań. Istnieje wiele "zalet" i nie widzę żadnych "minusów" za używanie konstruktora.

LATE UPDATE

Również wiele imprez jednostki doktryny nie są wysyłane przy użyciu DQL.

+1

W rzeczywistości QueryBuilder warunkowo konstruuje kwerendę DQL w kilku krokach: D – Diablo

+0

Nigdy nie powiedziałem, że nie było. – drakonli

+1

To był tylko szybki przykład, twój kod robi to samo i faktycznie generuje DQL na końcu. Pytanie nie dotyczyło "czystego rozwiązania", ale "jak usuwać wiersze z bazy danych". Jaki jest najlepszy sposób skonstruowania tego DQL jest poza zakresem tego pytania, może to być queryBuilder, ale może to być również coś innego. Nie można powiedzieć, że konstruktor zapytań jest jedynym rozwiązaniem, ponieważ nie znasz przypadków użycia. –