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?

Allencoded
źródło
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;
                      });
Damith
źródło
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.

Raphael Pinel
źródło
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