代码之家  ›  专栏  ›  技术社区  ›  Leonardo Henriques

在上一个操作完成之前,在此上下文上启动了第二个操作。接口上的异步方法

  •  1
  • Leonardo Henriques  · 技术社区  · 8 年前

    当我试图 SaveChangesAsync() 从我实现的接口。此接口上的其他所有方法似乎都可以正常工作。在给出错误的任务之前,我调试了每个任务 IsCompleted 。我是新手,告诉我我做错了什么。

    UserController 只有构造函数

    private readonly IUserRepository _userRepository;
    private readonly IRoleRepository _roleRepository;
    
    public UserController(IUserRepository userRepository,IRoleRepository roleRepository)
    {
          _userRepository = userRepository;
          _roleRepository = roleRepository;
    }
    

    UserController/Edit

    public async Task<IActionResult> Edit(string id, EditViewModel model)
            {
                ApplicationUser user = new ApplicationUser();
                List<IdentityRole> listaRoles = new List<IdentityRole>();
                IdentityRole Role = new IdentityRole();
                List<IdentityRole> listaSelectedRoles = new List<IdentityRole>();
    
                //Atribuir o nomeUtilizador ao modelo do Post
                var modelTemp = await base.CreateModel<EditViewModel>(_userRepository);
                Task taskModel = base.CreateModel<EditViewModel>(_userRepository);
                await Task.WhenAll(taskModel);
                bool test = taskModel.IsCompleted; //to debug: test = true;
    
                model.NomeUtilizador = modelTemp.NomeUtilizador;
                modelTemp = null;
    
                //buscar o utilizador com o id à base de dados
                user = await _userRepository.FindByIDAsync(id);
                var boo = _userRepository.FindByIDAsync(id).IsCompleted;    //to debug: boo = true;
    
                //Buscar roles da bd para uma lista
                var task = _roleRepository.ToListAsync();
                listaRoles = await task;
                var t = task.IsCompleted; //to debug: t = true;
    
                (...)
    
                if (ModelState.IsValid)
                {
                    try
                    {
                        (...)
                        //Adicionar/remover roles a cada utilizador
                        foreach (var role in listaRoles)
                        {
                            await _userRepository.RemoveFromRoleAsync(user, role.Name); //tested here: true aswell
    
                            foreach(var selectedRole in listaSelectedRoles)
                            {
                                if (role.Id == selectedRole.Id)
                                {
                                   await _userRepository.AddToRoleAsync(user, selectedRole.Name);   //tested here: true aswell
                                }
                            }
                        }
                        user.Nome = model.Nome;
                        user.Email = model.Email;
                        user.UserName = model.Email;
                        user.PhoneNumber = model.Telemovel;
    
                        await _userRepository.UpdateAsync(user); //error
                    }
                    catch (DbUpdateConcurrencyException)
                    {
                        if (!await ApplicationUserExists(user.Id))
                        {
                            return NotFound();
                        }
                        else
                        {
                            throw;
                        }
                    }
                    return RedirectToAction(nameof(Index));
                }
                return View(model);
            }
    

    IUserRepository

    public interface IUserRepository : IDisposable
        {
            Task<List<ApplicationUser>> ToListAsync();
            Task<ApplicationUser> FindByIDAsync(string userId);
            Task<ApplicationUser> FindByNameAsync(string userName);
            Task<IList<string>> GetRolesAsync(ApplicationUser user);
            Task AddToRoleAsync(ApplicationUser user, string roleName);
            Task RemoveFromRoleAsync(ApplicationUser user, string roleName);
            Task<bool> AnyAsync(string userId);
            Task AddAsync(ApplicationUser user);
            Task DeleteAsync(string userId);
            void Update(ApplicationUser user);
            Task SaveChangesAsync();
            Task UpdateAsync(ApplicationUser user);
        }
    

    UserRepository 并非所有节省空间的方法

    public class UserRepository : IUserRepository
        {
            private readonly ApplicationDbContext _context;
            private readonly UserManager<ApplicationUser> _userManager;
    
            public UserRepository(ApplicationDbContext context, UserManager<ApplicationUser> userManager)
            {
                _context = context;
                _userManager = userManager;
            }
    
            public Task<ApplicationUser> FindByIDAsync(string userId)
            {
                return _context.ApplicationUser.FindAsync(userId);
            }
    
            public Task<ApplicationUser> FindByNameAsync(string userName)
            {
                return _context.ApplicationUser.SingleOrDefaultAsync(m => m.UserName == userName);
            }
    
            public Task<List<ApplicationUser>> ToListAsync()
            {
                return _context.ApplicationUser.ToListAsync();
            }
    
            public Task AddAsync(ApplicationUser user)
            {
                _context.ApplicationUser.AddAsync(user);
                return _context.SaveChangesAsync();
            }
    
            public Task<IList<string>> GetRolesAsync(ApplicationUser user)
            {
                return _userManager.GetRolesAsync(user);
            }
    
            public Task AddToRoleAsync(ApplicationUser user, string roleName)
            {
                _userManager.AddToRoleAsync(user, roleName);
                return _context.SaveChangesAsync();
            }
    
            public Task RemoveFromRoleAsync(ApplicationUser user, string roleName)
            {
                _userManager.RemoveFromRoleAsync(user, roleName);
                return _context.SaveChangesAsync();
            }
    
    
    
            public Task UpdateAsync(ApplicationUser user)
            {
                _context.Entry(user).State = EntityState.Modified;
                return _context.SaveChangesAsync();
            }
        }
    

    正如我所说,我调试了所有其他方法及其: Status = RanToCompletion 。 非常感谢。

    2 回复  |  直到 8 年前
        1
  •  3
  •   Evk    8 年前

    您的“存储库”中有几个方法可以启动异步操作,但不等待它们完成。因此,您需要修复这些方法:

    public async Task AddAsync(ApplicationUser user)
    {
        // need to await this one
        await _context.ApplicationUser.AddAsync(user);
        await _context.SaveChangesAsync();
    }
    
    public async Task AddToRoleAsync(ApplicationUser user, string roleName)
    {
        // same story
        await _userManager.AddToRoleAsync(user, roleName);
        await _context.SaveChangesAsync();
    }
    
    public async Task RemoveFromRoleAsync(ApplicationUser user, string roleName)
    {
        // same story
        await _userManager.RemoveFromRoleAsync(user, roleName);
        await _context.SaveChangesAsync();
    }
    
        2
  •  1
  •   henoc salinas    8 年前

    尝试更改此 用户存储库 :

        public Task UpdateAsync(ApplicationUser user)
        {
            _context.Entry(user).State = EntityState.Modified;
            return _context.SaveChangesAsync();
        }
    

    对此,用于返回的int值 _上下文。SaveChangesAsync() :

        public async Task<int> UpdateAsync(ApplicationUser user)
        {
                _context.Entry(user).State = EntityState.Modified;
                return await _context.SaveChangesAsync();               
        }