17

私はEntityFrameworkでいくつかの監査フックを見てきました。それらの多くは、新旧の値の比較を示しています。これは監査証跡には最適ですが、オブジェクトのスナップショットを探しています。

たとえば...製品を管理するアプリケーションがあるとします。製品には、複数の属性と関連する他のオブジェクトがあります。オブジェクトを10回変更するとします。また、これらのオブジェクトの変更の画面を表示できることも重要だとしましょう(監査証跡ではなく、読み取り専用形式で画面が実際にどのように表示されたか)。私が興味を持っているのは、これらの10個の変更すべて(表示したいものに応じて)の元のEF製品オブジェクト(関連するすべてのデータを含む)を取得し、それを使用して画面にバインドできることです。

SQL Serverを使用している場合、最近のシリアル化されたオブジェクトにはどのタイプ(XML、blobなど)を使用する必要がありますか?これを行うのは理にかなっていますか?

4

4 に答える 4

12

どれどれ。オブジェクト グラフを取得し、後で具体化できる形式でデータベースにシリアル化する必要があります。まさにこれを行うツールがあると思います。そのうちの 1 つが Entity Framework です。

あなたがやりたいことは非常に一般的なことです。ウィキエンジンを考えてみましょう。ウィキには、誰もが見るヒント リビジョンと、すべてのドキュメントのバック リビジョンが必要です。また、ウィキは、ヒント リビジョンが表示されるのとまったく同じ方法で、バック リビジョンを表示できる必要があります。したがって、両方に同じストレージ形式を使用する必要があります。

すべてのエンティティ タイプのバージョン管理を許可することを提案します。エンティティ タイプを編集する場合、ヒント リビジョンを編集し、以前の値を含むバック リビジョンを保存します。(新しいヒントを挿入する代わりにヒント リビジョンを編集する理由は、現在 ObjectContext に実体化されていない他のオブジェクトに、ヒントへのリンクではなく、ヒントへのリンクとして保存したいヒントへのリンクが含まれている可能性があるためです。バックリビジョン。)

必要に応じて、バック リビジョンが別のファイル グループに格納されるように、SQL Server テーブルを分割できます。これにより、ヒント リビジョンとバック リビジョンを別々にバックアップできます。

于 2009-09-21T15:10:00.823 に答える
5

First you need to add a set of properties to your tables:

  • Version - time of last modification (can also be autoincrementing counter instead of time).
  • LastModifiedBy - reference to the user which made last modification (if you store that).

Then you have several options about how to store your version history. You can

  1. Create a new table for each of the main tables you want to store history for. That history tables will have all the same fields as main table, but primary and foreign keys will not be enforced. For each foreign key also store Version of referenced entry at the time version was created.

  2. OR you can serialize everything interesting about your entity and store all that serialized blobs for all entities you want to version in one global history table (I personally prefer first approach).

How do you fill your history tables? Via update and delete triggers.

  • In update trigger for your entity - copy all previous values to the history table. For each foreign key - also copy current Version of referenced entity.
  • In delete trigger - basically do the same.

Note that more and more modern systems do NOT really delete anything. They just mark things as deleted. If you would want to follow this pattern (which has several benefits) - instead of deleting add IsDeleted flag to your entities (of course you then have to filter deleted entities out everywhere).

How do you view your history? Just use history table, since it has all the same properties as main table - should not be a problem. But - when expanding foreign keys - ensure that referenced entity Version is the same as you store in your history table. If it's not - you need to go to History table of that referenced entity and grab values there. This way you will always have a snapshot of how entity looked like at THAT moment, including all references.

In addition to all above - you can also restore state of your entity to any previous version.

Note that this implementation, while easy, can consume some space, because it stores snapshot, not only changes being made. If you want to just store changes - in update trigger you can detect what fields has been changed, serialize them and store in global history table. That way you can at least show in user interface what has been changed and by whom (though you might have troubles to reverting to some previous version).

于 2016-05-27T09:59:54.257 に答える
0

<SQL Server 2016またはAzure SQL.

https://docs.microsoft.com/en-us/sql/relational-databases/tables/temporal-tables?view=sql-server-ver15

ドキュメントから:

現時点で正しいデータだけでなく、任意の時点でテーブルに格納されているデータに関する情報を提供するための組み込みサポートを提供するデータベース機能。テンポラルは、ANSI SQL 2011 で導入されたデータベース機能です。

ここに、サードパーティのライブラリを使用せずに Entity Framework Core で実装する方法の完全なガイドを書きました。

https://stackoverflow.com/a/64244548/3850405

于 2020-10-07T13:10:47.723 に答える