Frage

Ich versuche, herauszufinden, die richtige Art und Weise zu atomar einen Zähler in einer Tabelle erhöht und die Verwendung diesen Wert erhöht als Pseudo-Display-only-ID für einen Datensatz in einem anderen.

Was ich habe, ist ein Unternehmen, Tisch und ein Arbeitsplatz Tisch. Ich möchte jedes Unternehmen seinen eigenen Satz von job_numbers haben. Ich habe eine Autoinkrement job_id haben, aber diese Zahlen sind für alle Unternehmen geteilt. dh: die Auftragsnummern sollten lückenlos für jedes Unternehmen im Allgemeinen erhöhen

.

ie:

  • Unternehmen (company_id, next_job_number)
  • Jobs (company_id, job_id, job_number)

Zur Zeit dies ich tue (als Methode auf dem Teiljobklasse):

public void SaveJob()
{
    using (var scope = new System.Transactions.TransactionScope())
    {
        if (job_id == 0)
        {
            _db.Update<company>()
                .SetExpression("next_job_number").EqualTo("next_job_number+1")
                .Where<company>(x => x.company_id == company_id)
                .Execute();

            company c = _db.companies.SingleOrDefault(x => x.company_id == company_id);

            job_number = c.next_job_number;
        }

        // Save the job
        this.Save();

        scope.Complete();
    }
}

Es scheint zu funktionieren, aber ich bin mir nicht sicher, ob es hier Gefahren? Es fühlt sich einfach falsch, aber ich bin nicht sicher, wie ich es anders zu tun.

Jede Beratung sehr geschätzt.

War es hilfreich?

Lösung

Zuerst

sollten Sie die Transaction in Verbindung mit einem SharedDbConnectionScope verwenden oder Ihrer Transaktion wird nicht funktionieren wie erwartet.

Zweitens

würde ich einen anderen Ansatz mit einer einzigen Anweisung und ohne die Notwendigkeit, die job_id mit der Firma speichern)

  1. Speichern Sie die Aufzeichnung mit job_number = 0

  2. Aktualisieren Sie den Datensatz mit so etwas wie dieses

    UPDATE JOBS SET JOB_NUMBER =     (SELECT MAX (job_number) +1 FROM JOBS WHERE company_id = 12345)     WHERE job_id = "+ this.job_id;

(Sie müssen nur diese Abfrage Unterschall Syntax konvertieren, benutze ich Subsonic3 nicht) Das sollte garantieren, dass die Auftragsnummer für jedes Unternehmen einzigartig ist (wenn Sie sowohl das Speichern und Update-Befehl in einer Transaktion wickeln und eine Tabellensperre verwenden).

Andere Tipps

dynamischen Code Mit dem aktuellen höchsten Wert bekommen kann riskant (potenzieller doppelte Wert) wird auf einem hohes Volumen Multi-User-System.

Ein weiterer Ansatz könnte sein, eine neue Tabelle mit zwei Spalten zu erstellen; ein ein Zeichen PK und die andere eine ganze Zahl des letzten relevanten Wert zu speichern. Jedes Mal, wenn Sie einen neuen Wert wollen, erhöhen Sie den Wert in dem Datensatz für das betreffende Unternehmen und verwenden diesen Wert für Ihre Auftragsnummer. Der Charakter PK würde umfasst so etwas wie:

"LAST_ORDER_NUMBER_COMPANY_" + company_id

Ich habe eine gespeicherte Prozedur aufrufen, die entweder automatisch einen neuen Rekord startet das erste Mal, wenn ein Unternehmen einen Auftrag hat, oder Inkrementen es für Folgeaufträge, und gibt die neue Bestellnummer Wert zurück.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top