0

テーブルのエンティティをアーカイブしようとしています。これを行うにはいくつかの方法があります。そのうちの 1 つは IsArchived 列を作成し、エンティティが削除または履歴に追加されたときに true に設定することです。この設計の欠点の 1 つは、特定のテーブルが非常に重くなることです。

これを行う別の方法は、ログに記録する指定エンティティのクラスの複製を作成し、別のテーブルを作成し、AutoMapper を使用してログ テーブルに追加することです。この場合、アーカイブする必要があるエンティティの重複クラスが多数必要です。

特定のエンティティをアーカイブするための他のソリューションはありますか?

4

3 に答える 3

1

最善の方法は、null 許容の ArchivedTimeStamp 列をテーブルに追加することです。このようにして、行がアーカイブされたかどうか、アーカイブされた場合はいつアーカイブされたかを知ることができます。

テーブルのサイズが心配な場合は、テーブルを分割して、アーカイブされた行をセカンダリ/低速の物理ディスクに自動的に移動できます。たとえば、1 年以上前にアーカイブされた行のみをセカンダリ パーティションに移動する必要があるように、パーティションを分割することもできます。

パーティショニングを使用した SQL アーカイブの詳細については、http://www.mssqltips.com/sqlservertip/2780/archiving-sql-server-data-using-partitioning/を参照してください。

于 2013-10-17T04:23:53.433 に答える
0

同じスキーマを持つ複数のデータベースを持つことができます。次に、異なる接続文字列を使用して、データベースごとに 1 つずつ、いくつかのコンテキストを開くことができます。一方をクエリし、エンティティを他方にアタッチして保存します。

私はこれをやったことがありませんが、うまくいくはずです。エンティティがソース コンテキストにアタッチされ、デスティネーションにアタッチできないため、問題が発生する可能性がありますが、エンティティをアタッチ解除して再アタッチする方法があります。

于 2013-10-15T20:31:48.117 に答える
0

元に戻す目的で論理的な削除を実装しました。私の答えは、論理的な削除に通常関連するいくつかの問題、つまり結合とインデックスを克服する方法を示しています。それは私の目的によく合っています。ただし、アーカイブに使用すると、テーブルが無限に大きくなります。

もう 1 つのアイデアは、重複したクラスを作成し、automapper を使用することです。それは多くの余分なコーディングのように聞こえます。

同じスキーマでデータベースを作成できると思いますが、おそらく主キーはデータベースで生成されず、外部キーは強制されません。次に、削除をオーバーライドして、データがコピーされるようにします。

このようなもの:

public override int SaveChanges()
{
   foreach (var entry in ChangeTracker.Entries()
             .Where(p => p.State == EntityState.Deleted 
             && p.Entity is ModelBase))//I have a base class for entities with a single 
                                       //"ID" property - all my entities derive from this
    CustomDelete(entry);

    return base.SaveChanges();
}

private void CustomDelete(DbEntityEntry entry)
{
    var e = entry.Entity as ModelBase;
    string tableName = GetTableName(e.GetType());
    string sql = String.Format(@"INSERT INTO archive.{0} SELECT * FROM {0} WHERE ID = @id; 
                                 DELETE FROM {0} WHERE ID = @id", tableName);
    Database.ExecuteSqlCommand(
             sql
             , new SqlParameter("id", e.ID));
    entry.State = EntityState.Detached;
}

EF6 では、ストアド プロシージャへのマッピングが使用されている場合、移行ファイル内の sql を変更することで、削除をオーバーライドすることもできることに注意してください。

于 2013-10-16T08:47:34.590 に答える