:: Не фоксом единым
C# узнать, что будет сохраняться
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
В EntityFrameworkCore в классе DbContext есть метод int SaveChanges(). Данный метод возвращает:

Цитата:
The number of state entries written to the database.

Что yandex переводит как

Цитата:
Количество записей состояния, записанных в базу данных.

Такой вопрос. А можно как то до сохранения получить список объектов, которые будут сохраняться? Т.е. если SaveChanges возвращает 2, то как увидеть эти самые два объекта? И увидеть, что именно в них изменилось?



Исправлено 1 раз(а). Последнее : S-type, 13.07.20 17:45
Ratings: 0 negative/0 positive
Re: C# узнать, что будет сохраняться
Аспид

Сообщений: 3475
Откуда: Москва
Дата регистрации: 01.04.2005
Возможно есть положительный ответ.
Но...
SaveChanges работает на уровне контекста, а не на уровне объектов.
Потому на мой взгляд, лучше писать код так, что бы такой необходимости не было)))
Изменили кучку связанных объектов, сохранили.
При кодировании, вам ясно что происходит.
А так...
Ну выдало программе кучу объектов, и что с этим делать?
Вовсе не убежден что прав, но это мое видение)

Как вариант перебрать EntityState всех объектов... упаси господь)))
Ratings: 0 negative/0 positive
Re: C# узнать, что будет сохраняться
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
docs.microsoft.com

ObjectStateManager.GetObjectState(нужные флаги изменений) и потом у полученных ObjectStateEntry дёргать GetModifiedProperties()

только я не очень понимаю смысла подобных действий в прикладном коде


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: C# узнать, что будет сохраняться
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
смысла подобных действий в прикладном коде
Ни чего делать с полученной информацией не планирую Смысл действий в контроле. Есть некая сложная логика, и хотелось бы проверить...
Ratings: 0 negative/0 positive
Re: C# узнать, что будет сохраняться
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Проверять имеет смысл тогда уж содержимое БД (полностью интеграционный тест - от UI до сохранённых данных), а вообще юнит-тесты должны контролировать сложную логику, и при этом вообще ни БД ни даже EF не требуется задействовать в тестах. Для того и делять код на слои и используют DI - контроллеры, сервисы, репозитории связанные между собой интерфейсами. Чтобы просто замокав тот же репозиторий проверить как отработал расчёт в сервисе. А не лезть куда-то на пол-пути между слоями, дабы увидеть внутреннюю кухню ORM-а.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: C# узнать, что будет сохраняться
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
ObjectStateManager.GetObjectState(нужные флаги изменений) и потом у полученных ObjectStateEntry дёргать GetModifiedProperties()
Пытаясь разобраться - зачем нужны эти методы, на github.com нашёл вот такой код:

var entry = db.Entry(item);
var propertyNames = entry.Metadata.GetProperties().Select(p => p.Name);
var modifiedProperties = propertyNames.Select(p => entry.Property(p)).Where(e => e.IsModified);

Здесь item - это элемент, в котором производится изменение.

Открыл entry.Property, нашёл там нужное поле, вижу:

[attachment 33522 s1.png]

Но, этого не может быть! Старое и новое значение разные, а флаг isModified=false.

Почему?



Исправлено 1 раз(а). Последнее : S-type, 15.07.20 16:15
Ratings: 0 negative/0 positive
Re: C# узнать, что будет сохраняться
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
В общем код такой (сразу скажу, это не мой код - достался по наследству):

public T Update(T item)
{
var exist = Get(item.Id); // по Id находим в базе запись
db.Entry<T>(exist).CurrentValues.SetValues(item); // устанавливаем isModified нужной записи в true (видимо, так задумывалось автором)
// добавлено мной для проверки
var entry = db.Entry(item);
var propertyNames = entry.Metadata.GetProperties().Select(p => p.Name);
var modifiedProperties = propertyNames.Select(p => entry.Property(p)).Where(e => e.IsModified);
return exist; // возвращаем изменённый объект
}

Если db.Entry<T>... заменить на dbSet.Update(exist) (тут dbSet = db.Set<T>()) - код работает. Но, в этом случае isModified получают true все поля всей записи. А хотелось бы только одной.



Исправлено 1 раз(а). Последнее : S-type, 15.07.20 17:51
Ratings: 0 negative/0 positive
Re: C# узнать, что будет сохраняться
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Для db (DbContext) вижу:

[attachment 33523 s2.png]

Хотя, по умолчанию должно быть true.

Поставил

db.ChangeTracker.AutoDetectChangesEnabled = true;

всё заработало, isModified стало true.

Остался вопрос - почему AutoDetectChangesEnabled = false. Перерыл весь класс, отнаследованный от dbContext - ни чего криминального... В чём может быть затык?



Исправлено 2 раз(а). Последнее : S-type, 15.07.20 19:32
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 9 (Гостей: 9)

© 2000-2024 Fox Club 
Яндекс.Метрика