Doctrine en MSSQL geven zelfde children terug

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • maarud
  • Registratie: Mei 2005
  • Laatst online: 14:52
Ik heb het grootste gedeelte van het intranet in MySQL + Symfony2 gemaakt wat prima werkt. Nu wil ik voor een klein gedeelte informatie ophalen uit de MSSQL database van het ERP pakket.

Om te voorkomen dat ik meerdere queries ga draaien om de informatie te verkrijgen (order + orderregels) wilde ik ook hiervoor Doctrine gebruiken omdat die met één join-query alles fetcht en ik dan redelijk efficient en met weinig code alle resultaten krijg.

Nu heb ik de entity nagemaakt op basis van de bestaande tabellayout (het is een read-onlyconnectie met MSSQL). Ik kan keurig de data fetchen met doctrine. Het wordt lastig als ik een LEFT JOIN uitvoer met de orderregels-tabel. Het aantal regels klopt, alleen ik krijg continu dezelfde regels terug.

Zoals het moet zijn:
code:
1
2
3
BEDRIJF X    2016-01    1234
BEDRIJF X    2016-01    5678
BEDRIJF X    2016-01    9101


Maar wat Doctrine teruggeeft:
code:
1
2
3
BEDRIJF X    2016-01    1234
BEDRIJF X    2016-01    1234
BEDRIJF X    2016-01    1234


Terwijl als ik de runnable query uitvoer op de SQL-Server, ik wel bovenstaande uitkomst krijg. De query is dus goed, maar Doctrine verwerkt hem niet goed.

Een exacte weergave van mijn entities staan in dit topic op SO waar ik helaas nog geen antwoord heb, dus ik dacht ik probeer het hier.

Het zit hem vast ergens in de relatie (mappedBy enzo) maar het lijkt allemaal goed want de runnable query is ook goed. Doctrine kan op de en of andere manier niet de juiste ID's pakken ben ik bang maar ik zie het niet meer....

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Begin eens met je informatie van SO ook hier posten. Het is leuk dat die ook al op SO staat maar je topic hier moet óók gewoon compleet zijn. ;)

Verder: je laat je query niet zien. Ik zie ook nergens of je het gewoon via entity mapping ophaalt, dus dit is een beetje gokken zo... Als je DQL hebt geschreven om de entiteiten op te halen, ben je dan niet vergeten om zowel de parent- als de child-table op te nemen in je select?

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • maarud
  • Registratie: Mei 2005
  • Laatst online: 14:52
Alright, de shortcut was misschien niet zo netjes idd, dus hier de aanvulling :)

Ordertabel in MSSQL
code:
1
2
3
4
PurchTable
recid = unique integer
purchid = unique string
en verder allerlei velden die minder belangrijk zijn (bedrijfsnaam, datum, etc).


Orderregels
code:
1
2
3
4
5
PurchLine
recid = unique integer
purchid = string
itemid = string
etc...


Dus, de nagemaakte entities:

Purchtable:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
 * @var integer
 *
 * @ORM\Column(name="recid", type="integer")
 */
private $recid;

/**
 * @var string
 *
 * @ORM\Column(name="purchid", type="string", length=255)
 * @ORM\Id
 */
private $orderid;

/**
 * @ORM\OneToMany(targetEntity="PurchLine", mappedBy="order")
 */
protected $lines;

public function __construct()
{
    $this->lines = new ArrayCollection();
}

In dit geval moest ik de purchid een ID-veld maken anders wilde Doctrine de OneToMany niet maken.

Purchline:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
 * @var integer
 *
 * @ORM\Column(name="recid", type="integer")
 * @ORM\Id
 */
private $recid;

/**
 * @var integer
 *
 * @ORM\Column(name="linenum", type="integer")
 */
private $linenum;

/**
 * @var string
 *
 * @ORM\Column(name="itemid", type="string", length=255)
 */
private $itemid;

/**
 * @ORM\ManyToOne(targetEntity="PurchTable", inversedBy="lines")
 * @ORM\JoinColumn(name="purchid", referencedColumnName="purchid")
 */
protected $order;


En de query:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public function findByPurchId($id)
    {
        $query = $this->getEntityManager()
            ->createQuery(
                'SELECT t, l
                FROM AppBundle:PurchTable t
                LEFT JOIN t.lines l
                WHERE t.orderid = :id'
            )->setParameter('id', $id);

        try {
            return $query->getSingleResult();
        } catch (\Doctrine\ORM\NoResultException $e) {
            return null;
        }
    }

Acties:
  • 0 Henk 'm!

  • Acid_Burn
  • Registratie: Augustus 2001
  • Laatst online: 08-10 17:33

Acid_Burn

uhuh

Ik vind het eigenlijk raar dat de koppeling via purchid loopt (string). Waarom is de connectie niet op het recordid (integer en primary key).

Glass Eye Photography | Zelfbouw wireless fightstick | Mijn puzzel site


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Acid_Burn schreef op dinsdag 29 maart 2016 @ 13:12:
Ik vind het eigenlijk raar dat de koppeling via purchid loopt (string). Waarom is de connectie niet op het recordid (integer en primary key).
Nou:
maarud schreef op dinsdag 29 maart 2016 @ 09:59:
Nu wil ik voor een klein gedeelte informatie ophalen uit de MSSQL database van het ERP pakket.
Klinkt alsof 'ie niet veel keus heeft. ;)

Hoe bepaal je dat je de verkeerde records terugkrijgt? Heb je al eens direct de lines in je entity geïnspect? Of zit daar nog een stapel logica tussen?

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • maarud
  • Registratie: Mei 2005
  • Laatst online: 14:52
Als ik dump() dan krijg ik ook in de dump de verkeerde lines terug. Ze hebben ook allemaal hetzelfde #nummer, dus Doctrine ziet ook dat ze identiek zijn. De aantallen kloppen wel (dus bij 3 lines krijg ik ook 3 resultaten in Doctrine, alleen zijn ze alledrie gelijk).

Op de een of andere manier ziet Doctrine niet dat de lines uniek zijn en geeft misschien daarom drie gelijke terug.

De entities zijn verder heel simpel, volgens het boekje. Geen logica behalve de annotations die in mijn post terug te vinden zijn.

Heb qua velden inderdaad geen keus, de MSSQL is read-only (mag beslist geen data terugschrijven) en ik moet dus namaken wat Microsoft bedacht heeft ;)

Acties:
  • 0 Henk 'm!

  • rewind.
  • Registratie: Oktober 2001
  • Laatst online: 10-10 23:40
Wat gebeurd er als je niet getsingleresult gebruikt maar getresult?

Acties:
  • 0 Henk 'm!

  • maarud
  • Registratie: Mei 2005
  • Laatst online: 14:52
Daar wordt het niet anders van, behalve dat het resultaat nu in een array zit omdat je meerdere zou kunnen verwachten:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
array:1 [
  0 => PurchTable {#551;
    -orderid: "xxxxxxxxxxxx"
    -createdAt: DateTime {#520}
    #lines: PersistentCollection {#550;
      -snapshot: array:4 [ ...4]
      -owner: PurchTable {#551}
      -association: array:15 [ ...15]
      -em: EntityManager {#484...10}
      -backRefFieldName: "order"
      -typeClass: ClassMetadata {#525}
      -isDirty: false
      -initialized: true
      -coll: ArrayCollection {#542;
        -elements: array:4 [▼
          0 => PurchLine {#544}
          1 => PurchLine {#544}
          2 => PurchLine {#544}
          3 => PurchLine {#544}
        ]
      }
    }
  }
]

Acties:
  • +1 Henk 'm!

Verwijderd

Aan de hand van de tabelnamen en de veldnamen is mij duidelijk welke ERP pakket er gebruikt wordt. Daardoor heb ik al een foutje kunnen bespeuren in uw scripts. Ik zie dat je de RecId veld hebt gedefinieerd als een Integer. In de database wordt RecId opgeslagen als een BigInt (Int64) tenzij je een oeroude versie gebruikt.

Acties:
  • 0 Henk 'm!

  • maarud
  • Registratie: Mei 2005
  • Laatst online: 14:52
Dat is het antwoord! Het veranderen van integer naar bigint heeft gewerkt. Prachtig!
Pagina: 1