Entity Framework无法从关联表中删除记录并引发错误

问题描述 投票:0回答:1

我有一个简单的关联表,在任何地方都未引用其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 /对象在代码中的多个位置使用-请让我知道如何清除它们-非常感谢。

请帮助吗?

entity-framework ef-code-first
1个回答
0
投票

已修复-问题是我们需要清除父对象正在使用的所有对象及其链接,然后只有我们才能保存更改,这是我的解决方法

    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);非常感谢所有试图帮助我的人

© www.soinside.com 2019 - 2024. All rights reserved.