Hopp Entities mens spyling når de er en Duplicate

stemmer
6

jeg spiller litt med Symfony2 og Doctrine2.

Jeg har en enhet som har en unik tittel for eksempel:

class listItem
{
    /**
     * @orm:Id
     * @orm:Column(type=integer)
     * @orm:GeneratedValue(strategy=AUTO)
     */
    protected $id;

    /**
     * @orm:Column(type=string, length=255, unique=true)
     * @assert:NotBlank()
     */
    protected $title;

nå er jeg henter en json og oppdatere databasen med disse elementene:

$em = $this->get('doctrine.orm.entity_manager');

foreach($json->value->items as $item) {
    $listItem = new ListItem();
    $listItem->setTitle($item->title);
    $em->persist($listItem);
}

$em->flush();

fungerer fint første gang. men andre gang jeg får en SQL-feil (selvfølgelig):Integrity constraint violation: 1062 Duplicate entry

noen ganger min JSON-fil blir oppdatert og noen av elementene er nye, noen er ikke. Er det en måte å fortelle foretaket manager for å hoppe over duplikatfiler og bare sette inn de nye?

Hva er den beste måten å gjøre dette?

Takk for all hjelp. Legg igjen en kommentar hvis noe er uklart

Redigere:

hva som fungerer for meg er å gjøre noe som dette:

$uniqueness = $em->getRepository('ListItem')->checkUniqueness($item->title);
    if(false == $uniqueness) {
        continue;
    }

    $listItem = new ListItem();
    $listItem->setTitle($item->title);
    $em->persist($listItem);
    $em->flush();
}

checkUniqueness er en metode i min listitem Repo som sjekker om tittelen er allerede i min db.

det er forferdelig. dette er 2 databasespørringer for hvert element. dette ender opp ca 85 databasespørringer for denne handlingen.

Publisert på 17/04/2011 klokken 16:46
kilden bruker
På andre språk...                            


2 svar

stemmer
1

Hva med å hente alle de aktuelle titlene i en rekke først og sjekke innsettings tittelen mot dagens titler i denne matrisen

$existingTitles = $em->getRepository('ListItem')->getCurrentTitles();

foreach($json->value->items as $item) {
  if (!in_array($item->title, $existingTitles)) {
    $listItem = new ListItem();
    $listItem->setTitle($item->title);
    $em->persist($listItem);
  }
}

$em->flush();

getCurrentTitles () måtte legges til listitem Repo å bare returnere en rekke titler.

Dette krever bare en ekstra DB spørring, men koster deg mer i minne til å holde dagens titler i en matrise. Det kanskje problemer med denne metoden hvis datasettet for listitem er veldig stor.

Hvis antall gjenstander du ønsker å sette inn hver gang er ikke for stor, kan du endre getCurrentTitles () -funksjonen til å spørre etter alle disse elementene med titlene du prøver å sette inn. På denne måten maks mengde $ existingTiles kommer du tilbake vil være størrelsen på innsatsen dataliste. Deretter kan du utføre sjekker som ovenfor.

// getCurrentTitles() - $newTitles is array of all new titles you want to insert
return $qb->select('title')
   ->from('Table', 't')
   ->in('t.title = ', $newTitles)
   ->getArrayResult();
Svarte 20/04/2011 kl. 13:18
kilden bruker

stemmer
0

Hvis du bruker en enhet som kan allerede finnes i manager du må slå det sammen.

Her er hva jeg ville gjøre (ikke teste det ennå):

$repository = $this->get('doctrine.orm.entity_manager');

foreach($json->value->items as $item) {
    $listItem = new ListItem();
    $listItem->setTitle($item->title);
    $em->merge($listItem); // return a managed entity
    // no need to persist as long as the entity is now managed
}

$em->flush();
Svarte 27/04/2011 kl. 11:30
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more