【问题标题】:Repository Pattern With asynchronous带有异步的存储库模式
【发布时间】:2020-11-03 23:57:34
【问题描述】:

我在我的存储库中编写了这段代码

Task<bool> UpdateUserAsync(User user);

但是我不知道如何在implementer类中编写补充代码 此代码接收用户的信息并在数据库中对其进行编辑 鉴于此方法必须是异步的

【问题讨论】:

标签: c# asp.net asynchronous async-await repository


【解决方案1】:

您的问题是在异步部分还是在“获取和更新用户”部分?

“获取和更新用户”的部分如果不告诉我们您访问数据库的方法很难描述:您使用的是实体框架吗? SQL?

SQL、DbConnection、DbCommand

假设您已经有同步方法:

public User FetchUserById(int userId) {...}
private void UpdateExistingUser(User user) {...}

您必须创建类似的异步方法:

public Task<User> FetchUserByIdAsync(int userId);
private Task UpdateExistingUserAsync(User user);

如果您使用 SQL,您可能会使用类DbCommand 和方法ExecuteReaderExecuteNonQuery。对于您的异步方法,请使用类似的异步方法。

注意:要使用 DisposeAsync,您需要 C# 8。否则使用 try ... finally 并显式调用 DisposeAsync

private async dbConnection CreateFetchUserCommand(
    DbConnection Connection,
    int userId)
{
    var dbCommand = connection.CreateCommand();
    dbCommand.CommandText = ...
    var dbParameter = dbCommand.CreateParameter();
    ... // etc.
    return dbCommand;
}

private async DbCommand CreateUpdateUserCommand(DbConnection connection, User user)
{
    var dbCommand = connection.CreateCommand();
    dbCommand.CommandText = ...
    var dbParameter = dbCommand.CreateParameter();
    ... // etc.
    return dbCommand;
}

public Task<User> FetchUserByIdAsync(int userId)
{
    using (var dbConnection = new DbConnection(...))
    {
        await dbConnection.OpenAsync();
        using (var dbCommand = dbConnection.CreateFetchUserCommand(dbConnection, userId))
        {
            using (var dataReader = await dbCommand.ExecuteReaderAsync())
            {
                 // use async methods to access fetched data
                 User user = await ...
                 return user;
            }
        }
    }
}

类似地:添加一个类似于您现有的 UpdateUser 的 UpdateExistingUserAsync。

public UpdateUser(User user)
{
    // TODO: exception if user null

    User existingUser = await FetchUserById(user.Id);
    if (existingUser == null)
    {
        // user does not exist
    }
    else
    {
        ... // copy values from user to existingUser
        await UpdateExistingUserAsync(existingUser); 
    }
}

从用户复制到现有用户可以只更新您提供的值。如果您总是想更新完整的用户,则不需要 FetchUserById。

实体框架

using (var dbConext = new MyDbContext(...))
{
    User existingUser = await dbConnection.Users.FindAsync(user.Id)
    if (existingUser != null)
    {
        ... // copy values from user to existingUser
        await dbContext.SaveAsync();
}

【讨论】:

    【解决方案2】:

    我不完全确定你想做什么,发布你的代码,你可能会得到更好的回应,但如果你问的是如何编写异步方法,那么它非常简单明了。

    如果您引用的“存储库”是一个接口,并且您正在询问如何异步编写实现,那么您需要执行以下操作:

    public async Task<bool> UpdateUserAsync(User user){
      // Check the user exists
      var existingUser = await GetUserAsync(user.Id);
    
      if (existingUser == null) {
        return false;
      }
    
      var success = await DoMySaveTransactions(); // This would be where you commit to your chosen backend.
      return success;
    }
    

    如果您询问如何使用您的新存储库,那么您可以在使用 async 修饰的方法中使用类似以下的内容。

    async void UpdateUsername(User existingUser, string newUsername) {
      existingUser.username = newUsername;
      var success = await _myRepository.UpdateUserAsync(existingUser);
    
      // Do something with success.
    }
    

    如果您想在非异步方法中使用实现,那么您的代码将类似于...

    
    void UpdateUsername(User existingUser, string newUsername) {
      existingUser.username = newUsername;
      var success = myRepository.UpdateUserAsync(existingUser).GetAwaiter().GetResult();
    
      // Do something with success.
    }
    
    

    如果我误解了您要执行的操作,请添加更多解释。

    【讨论】:

    • 谢谢 我想为用户面板部分准确地编写这段代码 在用户面板部分里面有许多文本框,包括电子邮件和密码以及用户名 用户可以更改它们 我想让这个用户进入我的Controller并将这个更改的信息保存在我的数据库中需要注意的是我使用asp.net核心技术
    • 你需要一个模型然后@ali,你需要将它发布到控制器方法。该模型需要前面的属性,然后您需要更新您的用户模型以反映上传的这些更改。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-02
    • 2023-03-21
    • 2021-11-15
    • 1970-01-01
    • 1970-01-01
    • 2016-09-22
    • 2011-03-09
    相关资源
    最近更新 更多