DbContextScope事务

时间:2016-08-03 21:01:01

标签: entity-framework transactions dbcontext

我使用mehdime/DbContextScope作为documented here来为我们的产品实施批量用户刷新/导入解决方案。

在标题“仅在调用SaveChanges()时保持更改”时,Mehdi在代码示例中说明:

  

在业务交易完成之前,请勿调用SaveChanges() -   即没有部分或中间保存。必须调用SaveChanges()   每个商业交易一次。

     

如果您发现需要多次调用SaveChanges()   在商业交易中,这意味着你实际上   在单个服务中实现多个业务事务   方法

但是,我想添加一个新行,获取其生成的ID(IDENTITY列),然后将一个审核日志条目添加到引用生成的ID的数据库中。为此,我需要执行一个中间SaveChanges(),以便EF执行INSERT并获取ID,但是我想在单个原子事务中执行此操作。

我是否遗漏了某些内容,或者在不违反Medhi规则的情况下实际可行吗?

这是我的代码示例(当前违反了规则)

    /// <summary>
    /// Creates a new Location
    /// </summary>
    /// <param name="orgID">ID of Organisation</param>
    /// <param name="name">Location Name</param>
    /// <returns></returns>
    public IActionResult Create(int orgID, string name)
    {
        if (string.IsNullOrEmpty(name))
            throw new ArgumentNullException(nameof(name));

        // New Location
        var location = new Location {
            OrganisationID = orgID,
            Name = name,
            Enabled = true
        };

        using (var dbContextScope = _dbContextScopeFactory.Create())
        {
            var ctx = dbContextScope.DbContexts.Get<PlatformEntities2014>();

            // Duplicate name?
            var existing = ctx.Locations.Where(l => l.OrganisationID == orgID && l.Name == name).FirstOrDefault();
            if (existing != null)
                return new ActionResult(ActionResultCode.ErrorAlreadyExists) { ReferencedObject = existing };

            ctx.Locations.Add(location);
            // ---POSITION A---
            dbContextScope.SaveChanges();   // (Assigns location.ID)

            // Log
            GeneralLog log = new GeneralLog() {
                DateTime = DateTime.Now,
                Code = "LOC",
                SubCode = "NEW",
                OrganisationID = orgID,
                Information = $"Location {location.ID} \"{location.Name}\" created during Bulk Refresh."
            };
            ctx.GeneralLogs.Add(log);
            // ---POSITION B---
            dbContextScope.SaveChanges();

            return new ActionResult(ActionResultCode.Success) { ReferencedObject = location };
        }
    }

位置A 中的第一个dbContextScope.SaveChanges();替换为ctx.SaveChanges();以获取ID并在 POSITION B处拨打dbContextScope.SaveChanges();是否可以接受

感谢。

1 个答案:

答案 0 :(得分:2)

继续解释评论中的关系。这是两个独立的商业交易。以这种方式看待它,如果它不能创建一个&#39; GeneralLog&#39;你的交易不被视为失败。因此,我会说这是两个单独的交易。记录不应该使您的业务交易失败。您可以做的是在一个事务中首先创建对象。获取ID并在单独的事务中创建日志。