如果我有一张表:
StudentId | ... | SchoolId
___________|_____|__________
1 | ... | SchoolA
2 | ... | SchoolA
3 | ... | SchoolB
...
我想删除学校列表,从schoolA到schoolZ(使用LINQ-to-SQL):
foreach(School s in schools){
db.Schools.DeleteOnSubmit(s);
db.submitChanges();
}
由于上面的FK引用, SchoolA
和SchoolB
将失败
如何继续删除所有其他学校,丢弃发生例外的学校?
答案 0 :(得分:6)
只包括没有学生的学校:
var schoolsToDelete = schools.Where(x => !x.Students.Any());
db.Schools.DeleteAllOnSubmit(schoolsToDelete);
db.submitChanges();
答案 1 :(得分: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演示的有效记录要好得多。
答案 2 :(得分:0)
我同意Mark Cidade,但我可以建议改进使用连接范围向数据库服务器发送单个请求。
答案 3 :(得分:0)
我同意Mark的解决方案。如果您不想删除学校及其学生,您可以使用:
foreach (School s in schools)
{
db.Students.DeleteAllOnSubmit(s.Students);
db.Schools.DeleteOnSubmit(s);
}
db.submitChanges();
这样你就可以实现FK约束,因此不会抛出任何错误。
答案 4 :(得分:-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;
}
}