Domanda

Sono nuovo in Entity Framework e ho problemi con qualcosa che era abbastanza facile in puro T-SQL. Supponiamo che abbiamo tabella con 3 colonne. Id (identità, chiave primaria), IdKind (int), numero (int). Colonna nubmer dipende dalla colonna IdKind. I dati di questa tabella dovrebbe essere simile a questo:

Id | IdKind | Numero

1 | 1 | 1

2 | 1 | 2

3 | 1 | 3

4 | 2 | 1

5 | 2 | 2

6 | 2 | 3

Come si può vedere il numero di colonna è auto incrementato dipende IdKind. In T-SQL Trovavo max (numero) + 1 per qualche IdKind. Tutto era in una stored procedure in una transazione così valore del numero è stato unico per IdKind.

Come realizzare lo stesso in Entity Framework. Valore del numero deve essere calcolata al momento della creazione nuovo oggetto o quando si cambia IdKind.

È stato utile?

Soluzione

I userebbe trigger del database per quella e proprietà Number configurare nella mappatura EF con StoreGeneratedPattern.Computed di informare EF che questa proprietà è riempito nel database e deve essere ricaricata dopo ogni aggiornamento / inserimento.

Vorrei anche non utilizzare max () per ogni nuovo numero. Invece vorrei mantenere la tabella di simulazione di sequenze separate. Questa tabella dovrebbe contenere record per la sequenza - nel vostro caso record per IdKind con il maggior numero corrente. Invece di selezionare l'aggregazione si seleziona singolo record e aggiornarlo per contenere nuovo numero max. Lavorare con questo tavolo deve essere nella stessa transazione come persistente modifiche al tuo organismo.

Altri suggerimenti

Ho avuto lo stesso problema, ma ho risolto in C #.

I dovrebbe avere un'entità mappato alla tabella:

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

I dovrebbe avere e l'entità ausiliarie per memorizzare l'ultimo numero utilizzato per Tipo.

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

Quindi prima di aggiungere una riga (oggetto MyEntity) al tavolo, mi dovrebbe calcolare il numero corretto utilizzando il campo LastNumber del LastNumberEntity con il genere uguale al mio valore Tipo.

Bisogna notare che questa strategia ha un problema di concorrenza perché due fili diversi potrebbe aggiungere un oggetto dello stesso tipo, allo stesso tempo, quei fili controllerà la stessa LastNumberEntity per ottenere il valore LastNumber. Questo problema ha una soluzione nota in EntityFramework. Il codice potrebbe aspetto:

 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");
    }

Questo metodo ottiene un numero incrementale per un determinato Tipo e maniglie problema di concorrenza, usando, possiamo impostare il valore numero per ciascun oggetto MyEntity. Il codice del client potrebbe aspetto:

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

Questo codice potrebbe essere riscritta, rendendo i setter privata, facendo una fabbrica per garantire i soggetti da sempre vengono creati utilizzando il metodo ControllaNumero e l'utilizzo di repository per gestire il db.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top