Zaktualizuj wiele wierszy w Entity Framework z listy identyfikatorów


95

Próbuję utworzyć kwerendę dotyczącą struktury jednostki, która pozwoli mi pobrać listę identyfikatorów i zaktualizować skojarzone z nimi pole.

Przykład w SQL:

UPDATE Friends
SET msgSentBy = '1234'
WHERE id IN (1, 2, 3, 4)

Jak przekonwertować powyższe na strukturę encji?


Jaka jest Twoja platforma bazodanowa Oracle mysql ..
— zee

Moja baza danych to Microsoft SQL
— kodowanie allen

Są na to dwa projekty open source: EntityFramework.Extended i E ntity Framework Extensions .
— Peter Kerr

Jedyna poprawna odpowiedź brzmi: nie możesz. Oczywiście, możesz pobrać wszystkie pasujące Friendpliki z bazy danych, zaktualizować ich właściwości msgSentByi zapisać zmiany. Ale EF będzie uruchamiać UPDATEinstrukcje dla każdego pojedynczego rekordu. To nie to samo, co zbiorcza aktualizacja z jednym oświadczeniem. Jak już powiedziano, poszukaj biblioteki innej firmy, która oferuje zbiorczą aktualizację.
— Gert Arnold

Odpowiedzi:


167

coś jak poniżej

var idList=new int[]{1, 2, 3, 4};
using (var db=new SomeDatabaseContext())
{
    var friends= db.Friends.Where(f=>idList.Contains(f.ID)).ToList();
    friends.ForEach(a=>a.msgSentBy='1234');
    db.SaveChanges();
}

AKTUALIZACJA:

możesz zaktualizować wiele pól, jak poniżej

friends.ForEach(a =>
                      {
                         a.property1 = value1;
                         a.property2 = value2;
                      });

czy mogę zaktualizować więcej niż jedno pole w powyższym, które właśnie wysłałeś, o co właśnie prosiłem. po prostu ciekawi Cię, czy możesz zrobić więcej? Również nie wygląda na to, że SubmitChanges już całkiem działa. Używam najnowszej struktury encji. Może SaveChanges ()?
— kodowane allencod

10
ForEachjest metodą włączoną Listi generalnie odradza się jej używanie, ponieważ nie jest to bardzo funkcjonalny sposób programowania. Po prostu używaj foreach (operatora) jak normalnej osoby.
— BlueRaja - Danny Pflughoeft

55
Użycie tego rozwiązania generuje jedno zapytanie aktualizujące dla każdego elementu na liście. Czy istnieje sposób, aby EF wykonał tylko jedno zapytanie, jak w pytaniu? ( UPDATE SomeTable SET SomeField = SomeValue WHERE Id IN (...))
— RamNow

19
Należy pamiętać, że jest to dość nieefektywny sposób rozwiązania tego problemu z perspektywy bazy danych. Nie tylko powoduje to wyświetlenie dużej instrukcji select obejmującej każdy wiersz z tabeli Friends, ale także wydaje oddzielne polecenie UPDATE dla każdego aktualizowanego rekordu. Więc zamiast wydawać jedno polecenie, wydajesz potencjalnie wiele poleceń, a także przesyłasz strumieniowo wiele danych z bazy danych.
— d512

1
@ShekharPankaj, w zasadzie to, co chcesz zrobić, to wydać polecenie SQL, takie jak "UPDATE Friends SET msgSentBy = '1234' WHERE ID IN (1, 2, 3, 4)". Nie sądzę, żeby EF miał w tym bezpośrednie wsparcie. Uważam, że istnieją rozwiązania innych firm w tym zakresie ( stackoverflow.com/questions/12751258/batch-update-delete-ef5 ), ale ich nie używałem. Innymi opcjami jest użycie surowego ADO.NET zamiast EF.
— d512

-1
var idList=new int[]{1, 2, 3, 4};
var friendsToUpdate = await Context.Friends.Where(f => 
    idList.Contains(f.Id).ToListAsync();

foreach(var item in previousEReceipts)
{
  item.msgSentBy = "1234";
}

Możesz użyć foreach, aby zaktualizować każdy element, który spełnia twój warunek.

Oto przykład w bardziej ogólny sposób:

var itemsToUpdate = await Context.friends.Where(f => f.Id == <someCondition>).ToListAsync();

foreach(var item in itemsToUpdate)
{
   item.property = updatedValue;
}
Context.SaveChanges()

Ogólnie rzecz biorąc, najprawdopodobniej będziesz używać metod asynchronicznych z await dla zapytań db.


Nie widzę, jak to coś dodaje do istniejącej odpowiedzi. Po prostu to powtarza.
— Gert Arnold

główna różnica polega na używaniu foreach zamiast znajomych. ForEach
— Raphael Pinel
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.