Каков наилучший способ прозрачной регистрации изменений в объектах при использовании LINQ-to-SQL? - PullRequest
4 голосов
/ 16 декабря 2009

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

Таблица базы данных history выглядит следующим образом:

Item     | ItemId | Field     | WhenChanged         | OldValue | NewValue
customer | 6      | LastName  | 2009-12-31 13:00:04 | Sanders  | Sanders-Smith
customer | 5      | FirstName | 2009-12-31 12:11:14 | Jym      | Jim

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

Однако теперь мне нужно сделать доступным ведение журнала исторических данных из код . Он должен работать прозрачно при использовании LINQ-to-SQL , то есть разработчику не нужно выполнять никакой дополнительной работы, то есть следующий код должен вызывать запись в таблицу истории а также:

using (var db = Datasource.GetContext())
{
    var customers = from c in db.Customers
        where c.Status == "waiting"
        select c;
    foreach(var customer in customers)
    {
        customer.Status = "finished";
    }
}
db.SubmitChanges();

Я могу представить, что могу сделать это двумя способами:

  1. переопределить db.SubmitChanges () , но тогда возникает вопрос, как мне получить доступ к объектам, ожидающим изменений.
  2. присоединить мой метод регистрации к событию OnSubmitChanges , но я пока не смог найти решение этой проблемы

Кто-нибудь когда-нибудь работал над этой проблемой или знает хороший подход к ее решению?

Ответы [ 3 ]

2 голосов
/ 16 декабря 2009

Для вашего первого вопроса вы можете получить доступ к объектам, ожидающим изменений, с помощью db.GetChangeSet() и узнать, какие поля изменились и каково было исходное значение, вы можете использовать:

ITable table = db.GetTable(entity.GetType());
ModifiedMemberInfo[] modifiedMembers = table.GetModifiedMembers(entity);
object original = table.GetOriginalEntityState(entity);
2 голосов
/ 16 декабря 2009

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

Более подробную информацию вы можете найти в моем блоге по адресу http://farm -fresh-code.blogspot.com . Это слишком сложно, чтобы повторить здесь.

1 голос
/ 16 декабря 2009

Поскольку L2S генерирует код для вас, и вы хотите изменить поведение сгенерированного кода, я вижу две возможности:

  1. Вы начинаете использовать шаблоны T4 для генерации кода из файла dbml и изменяете шаблон для добавления своей функциональности. Этот метод описан здесь
  2. Вы добавляете функциональность к сгенерированному (частичному) классу datacontext, написав частичный класс самостоятельно. В вашем частичном классе вы можете реализовать методы создания / обновления / удаления (CreateCustomer, UpdateCustomer и DeleteCustomer), добавляя функциональность для сохранения изменений.

Я надеюсь, что эти указатели могут помочь вам на вашем пути.

...