信頼できない回避策を忘れてください(必要に応じて編集履歴を参照してください)。これを実行するためのはるかに信頼性の高い方法を見つけました。
まず、これに部分的なメソッドを使用することを忘れてください(たとえばUpdateTable1
、質問で)。インスタンスレコードのみのデータを変更しない限り、これはあまりうまく機能しません。したがって、インスタンス内の関連フィールドを更新する必要がある場合にのみ、これらの部分的なメソッドを保持しています。
SubmitChanges
これを行う方法は、部分DataContext
クラスのメソッドをオーバーライドすることです。これにより、デフォルトの処理を許可する前にSubmitChanges
(したがって、この機能をロックアウトする前に)、テーブルレコードの挿入/更新/削除が可能になります。
オーバーライド内では、DataContext
を使用して現在の変更セットにアクセスできますthis.GetChangeSet()
。これにより、すべての変更をループし、必要な追加のテーブル作業(ログレコードの追加など)を実行できます。
以下の例では、と呼ばれる標準のデータベーステーブルがTable1
あり、と呼ばれる一致するログテーブルがあると仮定します。内部にTable1Log
加えられた変更を記録して、ログテーブルに元のフィールドと同じフィールドがすべて含まれるようにしますが、それを拡張して保存します。 a (変更時)およびa (つまり、追加/編集/削除)。Table1
Table1Log
DateTime
LogType
これが私の最終的なコードの重要な部分です:
partial class MyDataContext
{
public override void SubmitChanges(System.Data.Linq.ConflictMode failureMode)
{
var set = this.GetChangeSet();//get a list of all pending changes
foreach (var item in set.Inserts)
{
AddLog(item, LogType.Add);
}
foreach (var item in set.Updates)
{
AddLog(item, LogType.Edit);
}
foreach (var item in set.Deletes)
{
AddLog(item, LogType.Delete);
}
base.SubmitChanges(failureMode);//allow the DataContext to perform it's default work (including your new log changes)
}
public void AddLog(object item, LogType logType)
{
//some painful type testing, so feel free to refactor this as you wish
if(item is Table1)
{
var log = (item as Table1).ToLog(logType);//ToLog() is an extension method (one for each type)
this.Table1_Logs.InsertOnSubmit(log);//add the log record ready to be submitted
}
else if(item is Table2)
{
//same again
}
//...repeat for each table class type
}
}
注:if / elseタイプのテストの代替は、ここにあります。私は実際にこれをコードで使用しましたが、非常にうまく機能します。パフォーマンス上の利点があるとは思えませんが、50以上のタイプを切り替える必要がある場合は、読みやすくするのに役立ちます。