How to avoid not-safe context operations in EF Core? [duplicate]

泪湿孤枕 提交于 2019-12-11 15:55:04

问题


I'd want to know how why creating instances of other classes with current database context instances as a parameter and using that db context causes this exception to be raised

'A second operation started on this context before a previous operation completed. Any instance members are not guaranteed to be thread safe.'

Imma use this sample code to show the problem

public class TestController : Controller
{
    private readonly DbContext dbContext;

    public Controller(DbContext ctx)
    {
        dbContext = ctx;
    }

    public async Task<IActionResult> Test(string id)
    {
        var isValid = new otherClass(dbContext).Validate(id);

        if (!isValid)
        {
            return View("error");
        }

        var user = dbContext.Users.FirstOrDefault(x => x.Id == id);

        user.Age++;

        dbContext.SaveChanges(); // exception is being raised here. It is second .SaveChanges() here  

        return View();
    }
}

public class otherClass
{
    private readonly DbContext dbContext;

    public otherClass(DbContext ctx)
    {
        dbContext = ctx;
    }

    public bool Validate(string id)
    {
        var user = dbContext.Users.FirstOrDefault(x => x.Id == id);

        user.ValidationAttempt = DateTime.Now;

        dbContext.SaveChanges();

        return user.HasConfirmedEmail;
    }
}

回答1:


Generally in an MVC fashion youre going to want a DbContext on a per request basis but when using threading more control through using blocks can be beneficial, an easy way to set that up would be something along the lines of

public class TestController : Controller
{
    private readonly Func<DbContext> dbContext;

    public Controller(Func<DbContext> ctx)
    {
        dbContext = ctx;
    }

    public async Task<IActionResult> Test(string id)
    {
        using(var cntx = dbContext())
        {
        var isValid = new otherClass(cntx).Validate(id);

        if (!isValid)
        {
            return View("error");
        }

        var user = cntx.Users.FirstOrDefault(x => x.Id == id);

        user.Age++;

        cntx.SaveChanges();  

        return View();
    }
    }
}

that essentially resolves a new DbContext per using block - and since each thread is then handling its own DbContext - shouldnt have any issues



来源:https://stackoverflow.com/questions/53150930/how-to-avoid-not-safe-context-operations-in-ef-core

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!