Transactions with ASP.NET Core 1.0 Identity UserManager

对着背影说爱祢 提交于 2019-12-08 03:56:11

问题


In one of my apps, I'm rewriting Asp Core Identity UserManager's CreateAsync, to in addition to creating new user in UserStore - create a new row in a separate statistics table (on a different dbcontext). Problem is, I would like both of those operations to be fired inside a transaction, so that if one fails - the other does not commit. Here's the code :

public override async Task<IdentityResult> CreateAsync(TUser user, string password)
    {
        // We need to use transactions here.            
            var result = await base.CreateAsync(user, password);

            if (result.Succeeded)
            {
                var appUser = user as IdentityUser;

                if (appUser != null)
                {
                    // create user stats.
                    var userStats = new UserStats()
                    {
                        ActionsCount = 0,
                        EventsCount = 0,
                        FollowersCount = 0,
                        ProjectsCount = 0,
                        UserId = appUser.Id
                    };

                    _ctx.UserStats.Add(userStats);
                    await _ctx.SaveChangesAsync();
                }
            }    
            return result;
    }

Thing is, I have no idea how to set up such a transaction, as it seems TransactionScope is not a part of .Net Core yet (?) and getting currently scoped DbContext for base.CreateAsync() with HttpContext.GetOwinContext() does not work as HttpContext seems to be missing this method (referencing Microsoft.Owin.Host.SystemWeb or Microsoft.AspNet.WebApi.Owin as hinted in some other stack overflow answers won't do - both are not compatible with .netcore). Any help ?


回答1:


Firstly you need to setup the dbcontext you are using with identity with a scoped lifetime:

        services.AddDbContext<MyDbContext>(ServiceLifetime.Scoped); // this is the important bit

        services.AddIdentity<User, Role>(options =>
        {
        })
        .AddEntityFrameworkStores<MyDbContext, int>()
        .AddDefaultTokenProviders();

Then when you need to create a transaction you do the following:

        using (var transaction = await _myDbContext.Database.BeginTransactionAsync())
        {
            var result = await _userManager.CreateAsync(newUser, password);

            try
            {
                if (result.Succeeded)
                {
                    DBItem newItem = new DBItem();
                    _myDbContext.Add(newItem);

                    await _myDbContext.SaveChangesAsync();
                    transaction.Commit();
                }
            }
            catch (Exception e)
            {
                transaction.Rollback();
            }
        }



回答2:


I believe the following is the right direction:

using (var transaction = _context.Database.BeginTransaction())
{

}


来源:https://stackoverflow.com/questions/38084088/transactions-with-asp-net-core-1-0-identity-usermanager

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