Ho il seguente scenario:
Una funzione di business logic che usa ef6 verifica se esiste già un record. Se il record non esiste, viene inserito nel database.
Qualcosa come questo
if (!product.Skus.Any(s => s.SkuCodeGroup == productInfo.SkuCodeGroup && s.SkuCode == productInfo.SkuCode))
AddProductSku();
Ho più thread che chiamano questa funzione di business logic. Quello che succede è:
Se la funzione viene chiamata contemporaneamente con gli stessi parametri, entrambe le istanze verificano se il record esiste e non esiste. Quindi entrambe le istanze inseriscono lo stesso record.
Quando context.SaveChanges () viene chiamato nella prima istanza, tutto va bene. Ma il secondo SaveChanges () genera un'eccezione perché il record esiste già (esiste un indice univoco nel database).
Come posso implementarlo per evitare l'eccezione?
L'ho risolto usando un lock {}, ma crea un collo di bottiglia che non voglio.
Grazie.
Abbiamo dovuto affrontare questo stesso problema. Non c'è davvero una buona soluzione se non si desidera implementare un blocco nel codice. Devi anche essere sicuro che non ci sia, o non ci sarà in futuro, più modi in cui le nuove righe possano entrare nel database.
Quello che facciamo è valutare il messaggio di eccezione e se si tratta di un errore di chiave duplicato, noi semplicemente mangiamo l'eccezione. In realtà, non controlliamo nemmeno prima per vedere se esiste la riga. SQL Server lo farà comunque per noi. Quindi salva una ricerca ogni volta che facciamo un inserto. Questo approccio funziona per noi e la nostra applicazione. Può o non può funzionare in tutti i casi, a seconda di cosa si vuole fare dopo l'inserimento.