Шаблон репозитория: Как отслеживать состояние объекта при обновлении / удалении на основе фильтра? - PullRequest
0 голосов
/ 21 мая 2019

Я внедряю шаблон Repository (поверх Mongo DB) вместе с Unit of Work. Добавление / обновление / удаление объектов из хранилища просто обновляет список (отслеживание) в памяти состояния объекта, который затем используется модулем работы в его методе SaveChanges() для фактического выполнения операции CUD в базе данных.

Например, метод Repository.Add():

public void Add(TEntity entity)
{
    TrackingList[entity] = new EntityData<TEntity>(entity, EntityState.Added);
}

Затем в единице работы SaveChanges() реализация:

var addedEntities = repository.TrackingList.Values.Where(v => v.State == EntityState.Added).Select(v => v.Entity);
if (!addedEntities.Any())
    return;

// inserts the added entities to the Mongo DB collection
repository.Collection.InsertMany(addedEntities);

Это работает при явном выполнении операции CUD для определенных объектов. Тогда я могу управлять этим списком отслеживания.
Но сейчас я пытаюсь реализовать следующий метод:

DeleteWhere(Expression<Func<Entity, bool>> filter);

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

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

Как правильно сделать это, если вообще возможно?

1 Ответ

0 голосов
/ 18 июня 2019

Мне не известно о ORM, который реализует массовое удаление (условное или нет) и массовое обновление (условное или нет) функции с полное соблюдение UoW,Да;многие ORM поддерживают эти функции;но в этом случае UoW не соблюдается или частично соблюдается.Да, действие базы данных будет выполняться только при сбросе (SaveChanges(), как вы сказали);но копирование в памяти или состояние в памяти не гарантированно находятся в согласованном состоянии с базовой СУБД.

Существует причина для этого.Чтобы UoW работал, объект должен быть загружен в память.В случаях, описанных выше, это не гарантируется.Единственный способ заставить эти две функции работать под UoW - это загрузить эти объекты в память в фоновом режиме (если еще не загружен) и затем выполнить действие.Это будет очень неэффективно.Многие ORM предоставляют эти две функции, не соблюдая или частично соблюдая UoW.

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

Насколько мне известно, есть два способа отслеживать изменения:

  1. Флаг

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

  2. Снимок

    Таким образом, ORM поддерживает копию объекта, когда он был первоначально загружен.Фактически загруженный объект выставляется для изменений.При очистке фактическая сущность сверяется с оригинальной копиейТаким образом, вы можете обнаружить изменения на уровне участника.Память и другие общие расходы на управление здесь выше.

...