Frage

Ich bin neu im Entity Framework und habe ein Problem mit etwas, das in reinem T-SQL recht einfach war. Angenommen, wir haben Tabelle mit 3 Spalten. ID (Identität, Primärschlüssel), idkind (int), Nummer (int). Die Spalten -Nubmer hängt von der IDKind -Spalte ab. Daten in dieser Tabelle sollten so aussehen:

Id | Idkind | Nummer

1 | 1 | 1

2 | 1 | 2

3 | 1 | 3

4 | 2 | 1

5 | 2 | 2

6 | 2 | 3

Wie Sie sehen können, hängt die Spaltennummer automatisch inkrementiert von IDKind ab. In T-SQL fand ich Max (Nummer) + 1 für einige Idkind. In einer Transaktion war alles in einem gespeicherten Verfahren, daher war der Wert der Zahl für IDKind eindeutig.

Wie man das gleiche im Entitätsrahmen erreicht. Der Wert der Zahl sollte beim Erstellen eines neuen Objekts oder beim Ändern der IDKIND berechnet werden.

War es hilfreich?

Lösung

Ich würde dafür einen Datenbankauslöser verwenden und konfigurieren Number Eigenschaft in EF -Mapping mit StoreGeneratedPattern.Computed Um EF zu informieren, dass diese Eigenschaft in der Datenbank ausgefüllt ist und nach jedem Update / Einfügen neu geladen werden muss.

Ich würde auch nicht max () für jede neue Nummer verwenden. Stattdessen würde ich separate Tabellen simulierende Sequenzen beibehalten. Diese Tabelle sollte den Datensatz pro Sequenz enthalten - in Ihrem Fallsatz pro Fall IdKind mit aktueller maximaler Nummer. Anstatt die Aggregation auszuwählen, wählen Sie einen einzelnen Datensatz aus und aktualisieren sie, um eine neue MAX -Nummer zu enthalten. Die Arbeit mit dieser Tabelle muss in der gleichen Transaktion wie anhaltende Änderungen an Ihrem Unternehmen sein.

Andere Tipps

Ich hatte das gleiche Problem, aber ich habe es in C#gelöst.

Ich sollte eine Entität auf den Tisch kartieren lassen:

public class MyEntity
{ 
     Kind IdKind{get; set;}
     int Number{get;set;}
}

Ich sollte und eine Hilfsentität haben, um die zuletzt verwendete Zahl pro Art zu speichern.

public class LastNumber
{ 
     Kind IdKind{get;set;}
     int LastNumber{get;set;}
}

Vor dem Hinzufügen einer Zeile (MyEntity -Objekt) zur Tabelle sollte ich die richtige Zahl unter Verwendung des Feldes LastNumber der LastNumberentity mit der Art entsprechen, die meinem freundlichen Wert entspricht.

Wir müssen beachten, dass diese Strategie ein Parallelitätsproblem aufweist, da zwei verschiedene Threads gleichzeitig ein Objekt derselben Art hinzufügen. Diese Threads untersuchen dieselbe LastNumberentity, um den Wert von LastNumber zu erhalten. Dieses Problem hat eine bekannte Lösung in EntityFramework. Der Code könnte so aussehen:

 public int GetNumber(Kind idKind)
    {
        using (var db = new MyDataContext())
        {
            var lastNumber = db.LastNumbers.Single(x=>x.IdKind == idKind);
            for (int attemps = 0; attemps < 10;)
            {
                try
                {
                    lastNumber.LastNumber++;
                    db.SaveChanges();
                    return lastNumber.LastNumber;
                }
                catch (DbUpdateConcurrencyException ex)
                {
                    attemps++;
                }
            }
        }

        throw new Exception("Many concurrency calls");
    }

Diese Methode erhält eine inkrementelle Zahl für eine bestimmte Art und behandelt das Problem mit der Genauigkeit. Wenn Sie sie verwenden, können wir den Zahlenwert für jedes MyEntity -Objekt festlegen. Der Client -Code könnte so aussehen:

var entity = new MyEntity();
var number = GetNumber(entity.IdKind);
entity.Number = number;
db.MyEntities.Add(entity);
db.SaveChanges();

Dieser Code kann neu gestaltet werden, wodurch die Setter privat gemacht werden und eine Fabrik erstellt werden, um sicherzustellen, dass die Entitäten immer mithilfe der GetNumber -Methode erstellt werden und Repositories zur Verwaltung der DB verwendet werden.

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