当我不想要它时,ExecuteSqlCommand会自动调用SaveChanges()

时间:2014-02-07 02:56:23

标签: asp.net-mvc entity-framework entity-framework-5

在我使用Entity Framework 5的ASP.NET MVC项目中,我想要使用后端存储过程执行一项操作,因为它会影响许多不同的实体。存储过程的本质是我不需要或希望它被EF跟踪;我从一个实体调用它,然后该实体的值被复制到数据库中的另一个表中。问题是我似乎无法停止 EF调用SaveChanges(),即使我不想这样做。

这是我的存储库代码的截断版本:

public class SubmissionRepository : IRepository<RebateHeaderSubmission>
    {
        private readonly HbaRebatesContext _db;

        public SubmissionRepository()
        {
           _db = new HbaRebatesContext();
        }

        public void Add(RebateHeaderSubmission entity) . . .
        public RebateHeaderSubmission GetById(int id) . . .
        public IQueryable<RebateHeaderSubmission> GetAll() . . .
        public void Update(RebateHeaderSubmission entity) . . .

        public void Save()
        {
            _db.SaveChanges();
        }

        public void AcceptSubmission(RebateHeaderSubmission entity)
        {
            var param = new SqlParameter("Rebate_Entry_Id", entity.Id);
            _db.Database.ExecuteSqlCommand("EXEC dbo.AcceptSubmission @Id", param);
        }
    }
}

这是一个稍微截断的代码版本,调用AcceptSubmission()

public ActionResult Edit(RebateHeaderSubmission editedRecord, bool acceptSubmission = false)
{
    if (editedRecord.Id > 0 && ModelState.IsValid)
    {
        _db.Update(editedRecord);
    }
    else
    {
        return PartialView("_Edit", editedRecord);
    }

    _db.Save();

    if (acceptSubmission == false)
    {
        return RedirectToAction("Single", new { id = editedRecord.Id });
    }
    else
    {
        var repo = _db as SubmissionRepository;
        if (repo != null)
        {
            repo.AcceptSubmission(editedRecord);
        }
        return RedirectToAction("Single", new { id = editedRecord.Id });    
    }
}

但是在AcceptSubmission()中,只要调用_db.Database.ExecuteSqlCommand,执行就跳转到Save()方法,我得到DbUpdateConcurrencyException表示没有更新行。

我已经尝试更新方法来分离实体,但它没有做任何好处。这是我最有希望的尝试:

public void AcceptSubmission(RebateHeaderSubmission entity)
{
    try
    {
        var param = new SqlParameter("Rebate_Entry_Id", entity.Id);
        var context = ((IObjectContextAdapter)_db).ObjectContext;
        context.SaveChanges();
        context.Detach(entity);
        _db.Database.ExecuteSqlCommand("EXEC dbo.AcceptSubmission @Rebate_Entry_Id", param);
    }
    catch (DbUpdateConcurrencyException)
    {
        //Do nothing for now.
    }
} 

执行仍然跳到Save(),我的catch块甚至不起作用,因为异常发生在Save()方法中。无论如何让EF停止呼叫SaveChanges()

更新:两个小的澄清。首先,我正在调用的存储过程正在执行,它可以工作。所以AcceptSubmission()正在发挥作用。其次,当我说执行“跳转”到Save()时,实际发生的是,只要我运行_db.Database.ExecuteSqlCommand,就会引发异常,但它会在Save()中引发方法。我实际上并未点击AcceptSubmission()的结束括号,也未点击Save()的左括号。

1 个答案:

答案 0 :(得分:0)

事实证明我错误地诊断了这个问题。 EF没有“跳”到SaveChanges。实际上有两个活动线程,由Unobtrusive JavaScript错误引起,如this answer中所述。修复我的JavaScript中的错误修复了问题。