powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Сброс изменений загруженного из бд сущностного объекта
18 сообщений из 18, страница 1 из 1
Сброс изменений загруженного из бд сущностного объекта
    #39019913
Oleg5555
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!

Помогите, пожалуйста, разобраться с проблемой. Есть, как я думаю, достаточно стандартная задача. Но не хотелось бы изобретать велосипед для ее решения или использовать какие-то неоптимальные, неправильные решения.
Суть в следующем. По средствам EF6 загружается коллекция сущностных объектов. Коллекция отображается на форму. На форме отображается список элементов и подробно текущий элемент со всеми свойствами и связями. Пользователь редактирует текущий элемент, потом приходит к выводу, что что-то сделал не так. Ему необходимо предоставить кнопку "сброс". При нажатии на нее текущий, редактируемый элемент сбрасывается в состояние на момент загрузки. Все изменения откатываются. Причем как изменения в простых свойствах объекта, так и свойствах коллекциях связанных объектов, свойствах навигации (если что-то добавилось - убрать, удалилось - восстановить, было изменено - откатить изменения).
Т. к. EF хранить OriginalValues, предполагал что есть какой-то стандартный метод для такого случая. Типо reset(), например в классе DBEntityEntry. Но такого нет. Единственное что есть, Reload(). Но повторная загрузка из БД не нужна. Да и необходимо сбросить вместе с самим объектом и его определенные загруженные связи. В общем не пойдет. Есть вариант для сброса обойти все свойства объекта, для измененных в CurrentValues записать OriginalValues, состояние объекта поменять на Unchanged. Потом пройтись по всем свойствам коллекциям, проверить состояние каждого элемента коллекции, в зависимости от состояния выполнить соответствующие изменения (для добавленных удалить из коллекции, удаленные восстановить и т. д.), для измененных записать в CurrentValues OriginalValues. Но это кажется слишком замороченным и похоже на изобретение велосипеда. Может кто-то подскажет оптимальное, разумное решение? Спасибо.
...
Рейтинг: 0 / 0
Сброс изменений загруженного из бд сущностного объекта
    #39019944
ViPRos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Oleg5555,

а как там вообще происходит удаление?
допустим ты удалил Единицу измерения (ну есть у тебя такое право), а на нее есть ссылки из сотен таблиц, тысяч строк...
как ЕФ это делает?
...
Рейтинг: 0 / 0
Сброс изменений загруженного из бд сущностного объекта
    #39019945
ViPRos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот если это ЕФ валит на СУБД, то UNDO невозможен, потому его там и нет скорее
...
Рейтинг: 0 / 0
Сброс изменений загруженного из бд сущностного объекта
    #39020196
Oleg5555
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Не совсем понял про удаление. Наверное, вопрос связан с удалением у текущего редактируемого объекта некоторой связи. Удаляется же не сама первичная сущность на которую идет ссылка, а именно связь. К примеру, есть сущность генетическое исследование. У этой сущности есть ряд различных связей, например с сущностью полиморфизм. Ген. исследование имеет коллекцию полиморфизмов. Связь в базе многие ко многим, реализуется отдельной таблицей. Загружаем справочник ген. исследований. Встаем на некоторую текущую запись. По ней получаем всю подробную информацию, в том числе и список полиморфизмов данного исследования, это коллекция по навигационному свойству. Пользователь редактирует исследование. Добавляем новый полиморфизм в коллекцию из справочника, удаляем какой-то уже добавленный. В базе ничего не меняется, сохранение не запускалось. Потом принимает решение, что запутался и нажимает сброс, вся коллекция восстанавливается на момент загрузки.
Так же свойством-коллекцией данной сущности может быть не коллекция ссылок на некоторый справочник, а просто некоторая коллекция элементов не являющихся самостоятельными сущностями. но это в принципе не суть.
...
Рейтинг: 0 / 0
Сброс изменений загруженного из бд сущностного объекта
    #39020199
Oleg5555
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Неужели в EF нельзя просто реализовать такую, казалось бы достаточно очевидную задачу?
...
Рейтинг: 0 / 0
Сброс изменений загруженного из бд сущностного объекта
    #39020345
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Oleg5555,
она наверное реализована, только не вытащена наружу, ведь следит же прокси за полями ( что поля изменились, какие поля - что бы не упдатить весь табун).
Сделайте при открытии формы клон объекта, а при абортировании восстанавливайтесь из клона..
...
Рейтинг: 0 / 0
Сброс изменений загруженного из бд сущностного объекта
    #39020388
Oleg5555
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот и я про то. EF хранит же OriginalValues. Думаю, создание копии объекта не очень хорошая идея. Необходимо же не просто копировать простые свойства, а так же и ссылочные свойства, которые в свою очередь могут так же иметь сложную структуру. В идеале необходимо глубокое копирование объекта, что может породить определенные проблемы. Думаю, проще использовать тогда вариант который я описал в первом сообщении. Плюс получается мне для каждого элемента загруженной коллекции объектов необходимо хранить копию, в то время как сам EF и так хранит OriginalValues по самому объекту и связям.
...
Рейтинг: 0 / 0
Сброс изменений загруженного из бд сущностного объекта
    #39020677
Oleg5555
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Может у кого-то будут еще какие мысли? В каком направлении копать?
...
Рейтинг: 0 / 0
Сброс изменений загруженного из бд сущностного объекта
    #39020782
kmaw
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Oleg5555Добрый день!

Помогите, пожалуйста, разобраться с проблемой. Есть, как я думаю, достаточно стандартная задача. Но не хотелось бы изобретать велосипед для ее решения или использовать какие-то неоптимальные, неправильные решения.
Суть в следующем. По средствам EF6 загружается коллекция сущностных объектов. Коллекция отображается на форму. На форме отображается список элементов и подробно текущий элемент со всеми свойствами и связями. Пользователь редактирует текущий элемент, потом приходит к выводу, что что-то сделал не так. Ему необходимо предоставить кнопку "сброс". При нажатии на нее текущий, редактируемый элемент сбрасывается в состояние на момент загрузки. Все изменения откатываются. Причем как изменения в простых свойствах объекта, так и свойствах коллекциях связанных объектов, свойствах навигации (если что-то добавилось - убрать, удалилось - восстановить, было изменено - откатить изменения).
Т. к. EF хранить OriginalValues, предполагал что есть какой-то стандартный метод для такого случая. Типо reset(), например в классе DBEntityEntry. Но такого нет. Единственное что есть, Reload(). Но повторная загрузка из БД не нужна. Да и необходимо сбросить вместе с самим объектом и его определенные загруженные связи. В общем не пойдет. Есть вариант для сброса обойти все свойства объекта, для измененных в CurrentValues записать OriginalValues, состояние объекта поменять на Unchanged. Потом пройтись по всем свойствам коллекциям, проверить состояние каждого элемента коллекции, в зависимости от состояния выполнить соответствующие изменения (для добавленных удалить из коллекции, удаленные восстановить и т. д.), для измененных записать в CurrentValues OriginalValues. Но это кажется слишком замороченным и похоже на изобретение велосипеда. Может кто-то подскажет оптимальное, разумное решение? Спасибо.

такой сценарий - только клонировать перед изменением
...
Рейтинг: 0 / 0
Сброс изменений загруженного из бд сущностного объекта
    #39020805
ViPRos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Oleg5555,
выкинуть ЕФ :)
...
Рейтинг: 0 / 0
Сброс изменений загруженного из бд сущностного объекта
    #39020809
Oleg5555
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Что использовать вместо EF?
...
Рейтинг: 0 / 0
Сброс изменений загруженного из бд сущностного объекта
    #39020811
kmaw
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Oleg5555Что использовать вместо EF?

для вашего сценария не принципиально. можно с ним, можно без или что-то другое.
...
Рейтинг: 0 / 0
Сброс изменений загруженного из бд сущностного объекта
    #39021476
Winnipuh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ViPRosOleg5555,
выкинуть ЕФ :)

100%!
...
Рейтинг: 0 / 0
Сброс изменений загруженного из бд сущностного объекта
    #39021589
petalvik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Oleg5555Что использовать вместо EF?

DataSet/DataTable. Метод RejectChanges отменит все незафиксированные изменения.
...
Рейтинг: 0 / 0
Сброс изменений загруженного из бд сущностного объекта
    #39021784
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petalvikDataSet/DataTable. Метод RejectChanges отменит все незафиксированные изменения.

оо...
...
Рейтинг: 0 / 0
Сброс изменений загруженного из бд сущностного объекта
    #39023908
Oleg5555
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В принципе нашел вариант решения для EF. Как нормально оформлю - выложу.
...
Рейтинг: 0 / 0
Сброс изменений загруженного из бд сущностного объекта
    #39025765
Oleg5555
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Т. К. dbContext у меня обернуть в Repository, то наряду с методом SaveAll(), который просто вызывает SaveChanges, реализовал метод RejectAll(). Проблема была только с восстановлением удаленных сущностей, которые перед удалением были модифицированы и изменения не были сохранены. Для таких есть два варианта решения. В коде (1) и (2). (1) - использует обращение к базе, мне этого не нужно, поэтому я использую (2).

public class BaseRepository<TEntity, TKey, TContext> : IRepository<TEntity, TKey>
where TEntity : class, IEntity<TKey>
where TContext : DbContext, new()
{
}
...
Рейтинг: 0 / 0
Сброс изменений загруженного из бд сущностного объекта
    #39025767
Oleg5555
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Т. К. dbContext у меня обернуть в Repository, то наряду с методом SaveAll(), который просто вызывает SaveChanges() на контексте, реализовал метод RejectAll(). Проблема была только с восстановлением удаленных сущностей, которые перед удалением были модифицированы и изменения не были сохранены. Для таких есть два варианта решения. В коде (1) и (2). (1) - использует обращение к базе, мне этого не нужно, поэтому я использую (2).

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
public class BaseRepository<TEntity, TKey, TContext> : IRepository<TEntity, TKey>
     where TEntity : class, IEntity<TKey>
     where TContext : DbContext, new()
     {
          public virtual void RejectAll()
        {
            foreach (var entry in this.Context.ChangeTracker.Entries().Where(x => x.State != EntityState.Unchanged))
            {
                switch (entry.State)
                {
                    case EntityState.Modified:
                        //При установке состояния объекта в Unchanged из Modified 
                        //в CurrentValues записываются OriginalValues
                        entry.State = EntityState.Unchanged;
                        break;

                    case EntityState.Added:
                        entry.State = EntityState.Detached;
                        break;

                    case EntityState.Deleted:
                        //(1)
                        //entry.Reload();    

                        //(2)
                        DbPropertyValues originalValues = entry.OriginalValues.Clone();
                        //При установке состояния объекта в Unchanged 
                        //из Deleted в OriginalValues записываются CurrentValues
                        entry.State = EntityState.Unchanged;

                        //восстанавливаем OriginalValues
                        //если объект перед удалением был модифицирован, 
                        //то восстановление OriganalValues переведет объект в состояние Modified
                        entry.OriginalValues.SetValues(originalValues);

                        if (entry.State == EntityState.Modified)
                        {
                            //При установке состояния объекта в Unchanged из Modified 
                            //в CurrentValues записываются OriginalValues
                            entry.State = EntityState.Unchanged;
                        }
                        break;

                    default:
                        break;
                }
            }
        }
     }



Далее необходимо только перечитать сущность на форму, из Model в ViewModel (автоматическое отображение во View).
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Сброс изменений загруженного из бд сущностного объекта
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]