2

次のようなテーブルがある場合:

StudentId  | ... | SchoolId
___________|_____|__________ 
1          | ... | SchoolA
2          | ... | SchoolA
3          | ... | SchoolB
...

そして、schoolA から schoolZ までの学校のリストを削除したいと考えています (LINQ-to-SQL を使用)。

foreach(School s in schools){
    db.Schools.DeleteOnSubmit(s);
    db.submitChanges();
}

SchoolASchoolB上記の FK 参照のために失敗します

続行して他のすべての学校を削除し、例外が発生した学校を破棄するにはどうすればよいですか?

4

5 に答える 5

6

生徒がいない学校のみを含める:

var schoolsToDelete = schools.Where(x => !x.Students.Any());
db.Schools.DeleteAllOnSubmit(schoolsToDelete); 
db.submitChanges();
于 2011-08-30T14:51:50.037 に答える
1

既定では、LINQ to SQL は最初のエラーで失敗し、トランザクションをロールバックします。できる限りの作業を継続したい場合は、SubmitChanges で ConflictMode オーバーロードを渡して継続できるようにすることができます。「LINQ in Action」の次のサンプルでは、​​キューに入れられたすべての更新を発行し、ChangeConflictException を処理することによって発生した競合を出力しようとします。

try
{
    context.SubmitChanges(ConflictMode.ContinueOnConflict);
}
catch (ChangeConflictException)
{
    var exceptionDetail = 
        from conflict in context.ChangeConflicts
        from member in conflict.MemberConflicts
        select new
        {
            TableName = GetTableName(context, conflict.Object),
            MemberName = member.Member.Name,
            CurrentValue = member.CurrentValue.ToString(),
            DatabaseValue = member.DatabaseValue.ToString(),
            OriginalValue = member.OriginalValue.ToString()
        };
    exceptionDetail.Dump();
}

当然のことながら、Mark Cidade が示したように、積極的に有効なレコードのみを削除しようとする方がはるかに優れています。

于 2011-08-30T15:13:53.873 に答える
0

マークの解決策に同意します。学校とその生徒を削除したくない場合は、次を使用できます。

foreach (School s in schools)
{
    db.Students.DeleteAllOnSubmit(s.Students);
    db.Schools.DeleteOnSubmit(s);
}

db.submitChanges();

そうすれば、FK 制約を満たしているので、エラーはスローされません。

于 2011-08-31T09:48:56.853 に答える
0

私は Mark Cidade に同意しますが、結合スコープを使用して単一の要求をデータベース サーバーに送信する改善策を提案できます。

于 2011-08-30T16:22:37.253 に答える
-1

簡単な方法を見つけた

foreach(School s in schools){

    try{
        db.Schools.DeleteOnSubmit(s);

        db.submitChanges();
    }
    catch(SqlException exp){
        if(exp.Message.Contains("The DELETE statement conflicted with the REFERENCE constraint"))   //just checking if is FK reference
            db.Schools.InsertOnSubmit(s);   //=)
        else
            throw;

    }
}
于 2011-08-31T09:34:43.003 に答える