我有一个简单的关联表,在任何地方都未引用其PK,但是当我尝试以以下方式从其中删除记录时,出现错误。我先使用EF代码。任何帮助都将非常非常有帮助。预先感谢。
List<ViolationTypeNOV> novRels = UnitOfWork.Context.ViolationTypeNOVs.Where(x => x.NOVId == nov.NOVId).Include("ViolationType").Include("NOV").ToList();
foreach (ViolationTypeNOV o in novRels)
{
UnitOfWork.Context.ViolationTypeNOVs.Remove(o);
}
UnitOfWork.Context.SaveChanges();
这里是我收到的错误消息。如果未以任何方式引用表的PK,为什么它会因此错误而失败?只是听不懂:
操作失败:由于一个或多个外键属性不可为空,因此无法更改该关系。对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。
如果我正在通过SSMS运行,则同样的东西正在工作:
DELETE ViolationTypeNOVs
WHERE ViolationTypeNOVId = 2
为什么?
但是如果我通过如下上下文通过上下文运行相同的查询,则在调用SaveChanges
时会出现相同的错误:
foreach (ViolationTypeNOV o in novRels)
{
string str = string.Format("Delete ViolationTypeNOVs where ViolationTypeNOVId = {0}", new object[] { o.ViolationTypeNOVId });
UnitOfWork.Context.Database.ExecuteSqlCommand(str);
}
UnitOfWork.Context.SaveChanges();
似乎上下文中的某些对象没有为空或被删除,总之有一次可以全部清除它们吗?因为这些ID /对象在代码中的多个位置使用-请让我知道如何清除它们-非常感谢。
请帮助吗?
已修复-问题是我们需要清除父对象正在使用的所有对象及其链接,然后只有我们才能保存更改,这是我的解决方法
public bool Delete(NOV nov, bool performCommit = true)
{
System.Data.Entity.DbContextTransaction dbOperation = null;
if (performCommit)
dbOperation = UnitOfWork.BeginTransaction();
try
{
//-- Remove the Items - "foreach" approach was a problem
// http://weblogs.asp.net/ricardoperes/entity-framework-pitfalls-deleting-orphans
//------------------------------------------------------
// Remove the Violations that are in this NOV
//------------------------------------------------------
List<Violation> violationIdlist = new List<Violation>();
foreach (var v in nov.ViolationNOVs)
{
var a = UnitOfWork.ViolationRepository.GetAll().Where(z => z.ViolationId == v.ViolationId).FirstOrDefault();
violationIdlist.Add(a);
}
foreach (var v in violationIdlist)
{
var a = nov.ViolationNOVs.Where(x => x.NOVId == nov.NOVId && x.ViolationId == v.ViolationId)?.FirstOrDefault();
nov.ViolationNOVs.Remove(a);
}
nov.IssuedBy.Clear();
//deleting all OneToMany references to NOV
List<ViolationTypeNOV> novRels = UnitOfWork.Context.ViolationTypeNOVs.Where(x => x.NOVId == nov.NOVId).Include("ViolationType").Include("NOV").ToList();
nov?.ViolationTypeNOVs?.Clear();
//foreach (ViolationTypeNOV o in novRels)
//{
// UnitOfWork.Context.ViolationTypeNOVs.Remove(o);
// o?.ViolationType?.ViolationTypeNOVs?.Remove(o);
// nov?.ViolationTypeNOVs?.Remove(o);
//}
UnitOfWork.Context.ViolationTypeNOVs.RemoveRange(novRels);
List<ViolationNOV> violationNOVs = UnitOfWork.Context.ViolationNOVs.Where(x => x.NOVId == nov.NOVId).Include("Violation").Include("NOV").ToList();
nov?.ViolationNOVs?.Clear();
UnitOfWork.Context.ViolationNOVs.RemoveRange(violationNOVs);
List<CaseNOV> caseNOVs = UnitOfWork.Context.CaseNOVs.Where(x => x.NOVId == nov.NOVId).Include("Case").Include("NOV").ToList();
nov?.CaseNOVs?.Clear();
UnitOfWork.Context.CaseNOVs.RemoveRange(caseNOVs);
UnitOfWork.Context.SaveChanges();
if (dbOperation != null)
dbOperation.Commit();
LogHandler.LogInfo(2521, "Deleted NOV " + nov.NOVNumber);
return true;
}
catch (Exception ex)
{
LogHandler.LogError(2523, "Commit Fail in NOV Delete", ex);
if (dbOperation != null)
dbOperation.Rollback();
throw ex;
}
}
此语句解决了问题:UnitOfWork.Context.ViolationTypeNOVs.RemoveRange(novRels);非常感谢所有试图帮助我的人