Удаление (очистка) определенных записей из EF Core ChangeTracker

.NET 7/EF Core 7: у нас есть процесс, который отслеживает изменения в базе данных, и я не могу его контролировать. Это черный ящик.

Что я могу контролировать, так это методы сохранения этих изменений. В своей программе я хочу опустить записи, НЕ принадлежащие двум основным таблицам. Это хороший способ «очистить» эти записи с трекера? Или есть более приемлемый способ сделать это?

Наша база данных довольно мала: каждая таблица содержит <10 тыс. записей.

// first we only want to commit changes to Schedule and Vacation ONLY so get those entries which are not part of that set.
var unDbSets = context.ChangeTracker.Entries()
    .Where(e => e.Entity is not Schedule && e.Entity is not Vacation)
    .Where(p => p.State == EntityState.Added || p.State == EntityState.Deleted || p.State == EntityState.Modified)
    .ToList();

foreach (var unDbSet in unDbSets)
{
    if (unDbSet.State == EntityState.Added)
    {
        // entity was never in the DB so we just try detaching it. this way EF will stop tracking it and will not take any
        // actions to serialize changes against DB.
        // note: we had this originally to Unchanged but that throws an exception
        unDbSet.State = EntityState.Detached;
    }
    else
    {
        // entity was in the DB so we just change the state to unchanged and it will not do anything with it and EF will leave
        // it in its original state in the DB.
        unDbSet.State = EntityState.Unchanged;
    }
}

// finally save the tracker changes
context.SaveChanges();

«Это хороший способ «очистить» эти записи?» Вы вообще не указываете, почему вы хотите это сделать, поэтому мы не можем предложить вам лучшие методы.

Poul Bak 17.04.2024 20:36

В основном это предохранитель, чтобы, если они случайно будут добавлены в трекер, их просто удалили.

sinDizzy 17.04.2024 20:57

Я бы предпочел создать исключение. Вызывающая функция SaveChanges должна знать, что ее код неправильный или он пытался сделать что-то запрещенное. Если молча не сохранять данные, это может слишком долго оставаться незамеченным.

Gert Arnold 17.04.2024 23:14

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

sinDizzy 18.04.2024 00:11

Хорошо, видимо, над этой частью больше никто не работает.

Gert Arnold 18.04.2024 08:58
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
185
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Речь идет о том, как настроить защиту с помощью DbContext, чтобы избежать неразрешенных изменений. Вариант: я использовал интерфейс маркера, чтобы отметить, какие объекты разрешено обновлять:

Т.е.

public interface IEditableEntity {}

Это можно привязать к любому базовому классу сущностей, возможно, вам придется централизовать свойства, такие как LastModifiedBy и LastModifiedDateTime и т. д., если вы включите их обработку в DbContext. Затем нужно разобраться с отклонением правок, вставок и т. д. Я обычно занимаюсь этим индивидуально, так как могу захотеть сообщить подробности о том, какие изменения отбрасываются.

var unAllowedUpdates = ChangeTracker.Entries().Any(x => x.State == EntityState.Modified
    && !typeof(IEditableEntity).IsAssignableFrom(x.GetType())));

В конечном итоге вы выполнили удаление этих элементов из системы отслеживания изменений, отсоединив добавления и установив измененные значения в неизмененные. Однако, если вы хотите полностью отменить эти изменения, вам также следует вызвать ChangeTracker.Clear() после завершения SaveChanges(), если после сохранения можно выполнить дополнительные запросы к экземпляру DbContext. Например, предположим, что у меня есть объект «Поездка», который имеет эти расписания, и по какой-либо причине поездка может быть обновлена, и я не хочу, чтобы она сохранялась, но я хочу сохранить дополнения и обновления в расписаниях. При сохранении данных я могу установить для Trip значение Unchanged, чтобы эти изменения не записывались, но если код снова загрузит поездку из DbContext, он все равно получит мою измененную (но неизмененную) сущность Trip в кеше отслеживания. чем извлечение реального состояния данных. Если вы намерены отменить изменения, но по-прежнему готовы видеть возможные изменения после сохранения (которые на самом деле не сохранились), то вы не хотите очищать трекер изменений, но если вы хотите, чтобы отброшенные изменения отражались в любых дальнейших вызовах из этот экземпляр DbContext, то вам следует очистить трекер изменений после сохранения, если изменения были отменены/игнорированы.

Ааааааааа, это был своего рода дополнительный вопрос, но я не хотел засорять пост. Так что да, фактически после того, как произойдет SaveChanges, пользователь все равно сможет внести дополнительные изменения, а затем снова сохранить те же записи. Хорошо, позвольте мне протестировать это и вернуться через день или два.

sinDizzy 18.04.2024 00:14

Работает как задумано. Спасибо.

sinDizzy 24.04.2024 20:41

Другие вопросы по теме

Похожие вопросы

NLOG — перенаправить журналы одного метода контроллера webapi в определенный файл
Получить всех пользователей из каталога Azure с помощью API Graph на C#
Как добавить свойство, полученное из триггерной функции, во все журналы в устойчивой функции Azure?
Схема уже существует: носитель в .NET Core 8.0
Рабочей службе C# .NET Core необходимо войти в текстовый файл и таблицу базы данных в зависимости от настроек
Как обновить фотографию профиля пользователя с помощью UPN (имя участника-пользователя) с помощью API Graph в C#
Преобразовать таблицу данных в PDF с настраиваемым верхним и нижним колонтитулом в .net core 6 mvc с помощью itextsharp 5.5.13.3?
Показать сведения о неперехваченном исключении в пользовательском интерфейсе Blazor
Отношения «многие ко многим», определенные в EF Core Fluent API
Почему JsonSerializerContext генерирует пустой JSON для модели, содержащей свойства [ObservableProperty]?