Я стараюсь избегать вызова SaveChanges внутри цикла и вызывать его только один раз, когда цикл завершается.
Похоже, что в этом случае мне приходится вызывать SaveChanges на каждой итерации, вот небольшой пример.
У меня есть два объекта:
public class OrderRow
{
public int Id { get; set; }
public string PartNumber {get; set; }
public List Rows { get; set; }
}
public class ShipmentRow
{
public int Id { get; set; }
public string PartNumber {get; set; }
public int? OrderRowId { get; set; }
public OrderRow? OrderRow { get; set; }
}
Теперь мне нужно сопоставить одну или несколько строк таблицы отгрузки с одной строкой заказа, скажем, это данные внутри двух таблиц:
Таблица OrderRows
Идентификатор
Номер детали
111
A789
222< /td>
A789
< /div>
Таблица строк поставок
Идентификатор
Номер детали
OrderRowId
333
A789
null
В цикле я сопоставляю одну строку с другой (очень упрощенный пример):
foreach(var item in dbContext.OrderRow.ToList())
{
List sRows = dbContext.ShipmentRow
.Where(x=> x.PartNumber == item.PartNumber
&& x.OrderRowId == null)
.ToList();
foreach(var s in sRows)
{
item.Rows.Add(s)
}
dbContext.SaveChanges();
}
Теперь я хочу переместить SaveChanges() за пределы цикла и сохранить все сразу, но проблема в том, что если я удалю SaveChanges() из цикла на второй итерации, sRows будет содержать уже сопоставленные данные.
На первой итерации строка отгрузки с идентификатором 333 сопоставляется со строкой заказа с идентификатором 111, на второй итерации строка отгрузки 333 сопоставляется с заказом 222, даже если это никогда не следует извлекать из БД, поскольку он уже связан, но внешний ключ не добавляется до вызова SaveChanges.
Я пробовал добавить его вручную, но вызов базы данных sRow все равно видит OrderRowId как нулевой .
Мне нужно переместить SaveChanges наружу, потому что это слишком сильно замедляет работу.
Я думал, что EF достаточно умен, чтобы обнаружить это изменение... но возможно, я делаю что-то не так.
Возможное решение: проверьте, связана ли уже строка отгрузки, полученная из БД, с заказами:List orders = dbContext.OrderRow.ToList();
foreach(var item in orders)
{
List sRows = dbContext.ShipmentRow
.Where(x=> x.PartNumber == item.PartNumber
&& x.OrderRowId == null)
.ToList();
foreach(var s in sRows)
{
if(orders.SelectMany(x => x.Rows).Any(x => x.Id == s.Id))
continue;
item.Rows.Add(s)
}
}
dbContext.SaveChanges();
Вот решение ChatGPT: получить все и работать в оперативной памяти, может привести к большому использованию памяти при увеличении размера БД
var orderRows = dbContext.OrderRow.ToList();
var shipmentRows = dbContext.ShipmentRow.Where(x => x.OrderRowId == null).ToList();
foreach (var orderRow in orderRows)
{
var matchingShipmentRows = shipmentRows
.Where(x => x.PartNumber == orderRow.PartNumber && x.OrderRowId == null)
.ToList();
foreach (var shipmentRow in matchingShipmentRows)
{
orderRow.Rows.Add(shipmentRow);
shipmentRow.OrderRowId = orderRow.Id;
}
}
dbContext.SaveChanges();
Подробнее здесь: https://stackoverflow.com/questions/784 ... ge-tracker
Цикл Entity Framework Core 6 и трекер изменений ⇐ C#
Место общения программистов C#
-
Anonymous
1716018100
Anonymous
Я стараюсь избегать вызова SaveChanges внутри цикла и вызывать его только один раз, когда цикл завершается.
Похоже, что в этом случае мне приходится вызывать SaveChanges на каждой итерации, вот небольшой пример.
У меня есть два объекта:
public class OrderRow
{
public int Id { get; set; }
public string PartNumber {get; set; }
public List Rows { get; set; }
}
public class ShipmentRow
{
public int Id { get; set; }
public string PartNumber {get; set; }
public int? OrderRowId { get; set; }
public OrderRow? OrderRow { get; set; }
}
Теперь мне нужно сопоставить одну или несколько строк таблицы отгрузки с одной строкой заказа, скажем, это данные внутри двух таблиц:
Таблица OrderRows
Идентификатор
Номер детали
111
A789
222< /td>
A789
< /div>
Таблица строк поставок
Идентификатор
Номер детали
OrderRowId
333
A789
null
В цикле я сопоставляю одну строку с другой (очень упрощенный пример):
foreach(var item in dbContext.OrderRow.ToList())
{
List sRows = dbContext.ShipmentRow
.Where(x=> x.PartNumber == item.PartNumber
&& x.OrderRowId == null)
.ToList();
foreach(var s in sRows)
{
item.Rows.Add(s)
}
dbContext.SaveChanges();
}
Теперь я хочу переместить SaveChanges() за пределы цикла и сохранить все сразу, но проблема в том, что если я удалю SaveChanges() из цикла на второй итерации, sRows будет содержать уже сопоставленные данные.
На первой итерации строка отгрузки с идентификатором 333 сопоставляется со строкой заказа с идентификатором 111, на второй итерации строка отгрузки 333 сопоставляется с заказом 222, даже если это никогда не следует извлекать из БД, поскольку он уже связан, но внешний ключ не добавляется до вызова SaveChanges.
Я пробовал добавить его вручную, но вызов базы данных sRow все равно видит OrderRowId как нулевой .
Мне нужно переместить SaveChanges наружу, потому что это слишком сильно замедляет работу.
Я думал, что EF достаточно умен, чтобы обнаружить это изменение... но возможно, я делаю что-то не так.
[b]Возможное решение:[/b] проверьте, связана ли уже строка отгрузки, полученная из БД, с заказами:List orders = dbContext.OrderRow.ToList();
foreach(var item in orders)
{
List sRows = dbContext.ShipmentRow
.Where(x=> x.PartNumber == item.PartNumber
&& x.OrderRowId == null)
.ToList();
foreach(var s in sRows)
{
if(orders.SelectMany(x => x.Rows).Any(x => x.Id == s.Id))
continue;
item.Rows.Add(s)
}
}
dbContext.SaveChanges();
[b]Вот решение ChatGPT:[/b] получить все и работать в оперативной памяти, может привести к большому использованию памяти при увеличении размера БД
var orderRows = dbContext.OrderRow.ToList();
var shipmentRows = dbContext.ShipmentRow.Where(x => x.OrderRowId == null).ToList();
foreach (var orderRow in orderRows)
{
var matchingShipmentRows = shipmentRows
.Where(x => x.PartNumber == orderRow.PartNumber && x.OrderRowId == null)
.ToList();
foreach (var shipmentRow in matchingShipmentRows)
{
orderRow.Rows.Add(shipmentRow);
shipmentRow.OrderRowId = orderRow.Id;
}
}
dbContext.SaveChanges();
Подробнее здесь: [url]https://stackoverflow.com/questions/78498998/entity-framework-core-6-loop-and-change-tracker[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия