Próbuję zaktualizować rekord przy użyciu EF6. Najpierw znajdź rekord, jeśli istnieje, zaktualizuj go. Oto mój kod: -
var book = new Model.Book
{
BookNumber = _book.BookNumber,
BookName = _book.BookName,
BookTitle = _book.BookTitle,
};
using (var db = new MyContextDB())
{
var result = db.Books.SingleOrDefault(b => b.BookNumber == bookNumber);
if (result != null)
{
try
{
db.Books.Attach(book);
db.Entry(book).State = EntityState.Modified;
db.SaveChanges();
}
catch (Exception ex)
{
throw;
}
}
}
Za każdym razem, gdy próbuję zaktualizować rekord przy użyciu powyższego kodu, pojawia się ten błąd: -
{System.Data.Entity.Infrastructure.DbUpdateConcurrencyException: Przechowywanie instrukcji aktualizacji, wstawiania lub usuwania wpłynęło na nieoczekiwaną liczbę wierszy (0). Elementy mogły zostać zmodyfikowane lub usunięte od czasu załadowania elementów. Odśwież element ObjectStateManager
c#
entity-framework
entity-framework-6
ef-database-first
użytkownik1327064
źródło
źródło
catch (Exception ex){throw;}
jest zbędna i można ją całkowicie usunąć.Odpowiedzi:
Próbujesz zaktualizować rekord (co dla mnie oznacza „zmień wartość istniejącego rekordu i zapisz go z powrotem”). Musisz więc pobrać obiekt, wprowadzić zmiany i zapisać go.
źródło
db.SaveChanges()
zmodyfikowanych obiektów w kontekście aktualizuje bazę danych.SaveChanges
kontekst ocenia wszystkie śledzone obiekty w celu ustalenia, czy są one dodane, zmienione lub usunięte i wydaje odpowiedni kod SQL do podłączonej bazy danych.Przeglądałem kod źródłowy Entity Framework i znalazłem sposób na faktyczną aktualizację encji, jeśli znasz właściwość Key:
W przeciwnym razie sprawdź implementację AddOrUpdate pod kątem pomysłów.
Mam nadzieję, że to pomoże!
źródło
SaveChanges()
połączenie jest wymagane po ustawieniu wartości.Możesz użyć
AddOrUpdate
metody:źródło
.AddOrUpdate()
jest używany podczas migracji bazy danych, odradza się korzystanie z tej metody poza migracjami, dlatego znajduje się wEntity.Migrations
przestrzeni nazw.AddOrUpdate()
metoda jest przeznaczona do migracji i nie nadaje się do sytuacji, gdy trzeba tylko zaktualizować istniejący wiersz. W przypadku, gdy nie masz książki z odniesieniem do wyszukiwania (tj. Identyfikatorem), utworzy nowy wiersz i może być problemem w nadchodzących przypadkach (na przykład, masz interfejs API, który musi zwrócić ci odpowiedź 404 NotFound, jeśli spróbuj wywołać metodę PUT dla nieistniejącego wiersza).Więc masz encję, która jest aktualizowana i chcesz zaktualizować ją w bazie danych przy użyciu najmniejszej ilości kodu ...
Współbieżność jest zawsze trudna, ale zakładam, że chcesz, aby Twoje aktualizacje wygrywały. Oto, jak to zrobiłem w tym samym przypadku i zmodyfikowałem nazwy, aby naśladować twoje zajęcia. Innymi słowy, po prostu zmień
attach
naadd
i działa dla mnie:źródło
Powinieneś użyć metody Entry () na wypadek, gdybyś chciał zaktualizować wszystkie pola w swoim obiekcie. Pamiętaj również, że nie możesz zmienić identyfikatora pola (klucza), dlatego najpierw ustaw identyfikator na taki sam, jak podczas edycji.
źródło
Ten kod jest wynikiem testu polegającego na aktualizacji tylko zestawu kolumn bez zapytania o zwrócenie rekordu w pierwszej kolejności. Najpierw używa kodu Entity Framework 7.
Oto pełny kod:
źródło
Dla rdzenia .net
źródło
Oto najlepsze rozwiązanie tego problemu: W widoku dodaj wszystkie identyfikatory (klucze). Rozważ nazwanie wielu tabel (pierwsza, druga i trzecia)
W kodzie C #
źródło
Attach
wprowadzenie jednostki ustawi stan śledzenia naUnchanged
. Aby zaktualizować istniejącą jednostkę, wystarczy ustawić stan śledzenia naModified
. Według dokumentów EF6 :źródło
źródło
Znalazłem sposób, który działa dobrze.
źródło
Powinieneś usunąć
db.Books.Attach(book);
źródło
Oto moja metoda aktualizacji encji po RIA (dla przedziału czasu Ef6):
Zauważ, że
FrameworkTypeUtility.SetProperties()
to mała funkcja narzędzia, którą napisałem na długo przed AutoMapper na NuGet:źródło
Jak powiedział Renat, usuń:
db.Books.Attach(book);
Zmień również zapytanie wynikowe, aby używało „AsNoTracking”, ponieważ zapytanie to odrzuca stan modelu struktury encji. Uważa, że „wynik” jest teraz książką do śledzenia, a ty tego nie chcesz.
źródło
Spróbuj....
UpdateModel (książka);
źródło
Wiem, że już kilkakrotnie otrzymałem dobrą odpowiedź, ale podoba mi się poniższy sposób robienia tego. Mam nadzieję, że to komuś pomoże.
źródło
Ma to miejsce w przypadku Entity Framework 6.2.0.
Jeśli masz konkretny
DbSet
element, który należy zaktualizować lub utworzyć:Można to jednak również wykorzystać w przypadku
DbSet
klucza ogólnego z pojedynczym kluczem podstawowym lub złożonym kluczem podstawowym.źródło