Обновить несколько строк в Entity Framework из списка идентификаторов


95

Я пытаюсь создать запрос для структуры сущностей, который позволит мне взять список идентификаторов и обновить связанное с ними поле.

Пример в SQL:

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

Как мне преобразовать вышеперечисленное в структуру сущностей?


Какая у вас платформа базы данных Oracle mysql ..
zee

Моя база данных - Microsoft SQL
allencoded

Это позволяют два проекта с открытым исходным кодом: EntityFramework.Extended и E ntity Framework Extensions .
Питер Керр

Единственный правильный ответ: нельзя. Конечно, вы можете извлечь все подходящие Friends из базы данных, обновить их свойства msgSentByи сохранить изменения. Но EF будет запускать UPDATEоператоры для каждой отдельной записи. Это совсем не то же самое, что массовое обновление с одним оператором. Как уже говорилось, ищите стороннюю библиотеку, которая предлагает массовое обновление.
Герт Арнольд,

Ответы:


167

что-то вроде ниже

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

ОБНОВИТЬ:

вы можете обновить несколько полей, как показано ниже

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

Могу ли я обновить более одного поля в приведенном выше foreach, которое вы только что отправили, и это именно то, о чем я просил. просто интересно, могли бы вы сделать больше? Также не похоже, что SubmitChanges больше работает. Я использую последнюю версию Entity Framework. Может, SaveChanges ()?
изменено кодирование

10
ForEach- это метод List, и его обычно не рекомендуется использовать, потому что это не очень функциональный способ программирования. Просто используйте foreach (оператор) как нормальный человек.
BlueRaja - Дэнни Пфлугофт

55
Использование этого решения создает один запрос на обновление для каждого элемента в списке. Есть ли способ заставить EF выполнить только один запрос, как в вопросе? ( UPDATE SomeTable SET SomeField = SomeValue WHERE Id IN (...))
RamNow

19
Имейте в виду, что это довольно неэффективный способ сделать это с точки зрения базы данных. При этом не только выполняется большой оператор выбора, включающий каждую строку из таблицы Friends, но и выполняется отдельная команда UPDATE для каждой обновляемой записи. Таким образом, вместо того, чтобы вводить одну команду, вы потенциально можете запускать множество команд, а также передавать поток данных из своей базы данных.
d512 06

1
@ShekharPankaj, в основном то, что вы хотите сделать, это ввести команду SQL, например «UPDATE Friends SET msgSentBy = '1234' WHERE ID IN (1, 2, 3, 4)». Я не думаю, что у EF есть прямая поддержка для этого. Я считаю, что для этого есть некоторые сторонние решения ( stackoverflow.com/questions/12751258/batch-update-delete-ef5 ), но я их не использовал. Другой вариант - использовать необработанный ADO.NET вместо 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";
}

Вы можете использовать foreach для обновления каждого элемента, соответствующего вашему условию.

Вот пример в более общем виде:

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

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

В общем, вы, скорее всего, будете использовать асинхронные методы с ожиданием для запросов к базе данных.


Я не понимаю, как это что-то добавляет к существующему ответу. Он просто повторяет это.
Герт Арнольд,

основное отличие заключается в использовании foreach вместо друзей. ForEach
Рафаэль Пинель
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.