【问题标题】:Repository signature for asp.net core 2.1 controller action return typesasp.net core 2.1 控制器操作返回类型的存储库签名
【发布时间】:2018-11-26 09:32:42
【问题描述】:

我正在尝试修改我的 Asp.net Core 2.1 项目以使用新的控制器操作返回类型 (https://docs.microsoft.com/en-us/aspnet/core/web-api/action-return-types?view=aspnetcore-2.1#actionresultt-type)

他们给出的控制器示例是:

[HttpGet("{id}")]
[ProducesResponseType(200)]
[ProducesResponseType(404)]
public ActionResult<Product> GetById(int id)
{
    if (!_repository.TryGetProduct(id, out var product))
    {
        return NotFound();
    }

    return product;
}

但是,此方法的存储库签名是什么样的?

如果我尝试:

public async Task<Product> TryGetProduct(int id)

然后我收到一个错误,即没有采用 2 个参数的存储库方法。

但如果我尝试:

public async Task<Product> TryGetProduct(int id, out var product)

然后我得到:

异步方法不能有 ref 或 out 参数

【问题讨论】:

  • 这意味着你的方法签名不能有async关键字。您仍然可以返回 Task&lt;Product&gt; 以便它可以等待,但您不能在方法本身内进行任何等待。

标签: asp.net asp.net-core


【解决方案1】:

要保留异步任务功能,您可以这样做。

public interface IRepository
{
    Task<bool> TryGetProduct(int id, out Product product);
}

public class Repository : IRepository
{
    public Task<bool> TryGetProduct(int id, out Product product)
    {
        product = _db.Products.SingleOrDefault(x => x.Id == id);

        return Task.FromResult(product != null);
    }
}

然后在控制器中。

[HttpGet("{id}")]
[ProducesResponseType(200)]
[ProducesResponseType(404)]
public async Task<ActionResult<Product>> GetById(int id)
{
    // await 
    if (!await _repository.TryGetProduct(id, out var product))
    {
        return NotFound();
    }

    return Ok(product);
}

【讨论】:

    【解决方案2】:

    签名是

    public interface IRepository
    {
        bool TryGetProduct(int id, out Product product);
    }
    

    并且在实现中,如果您的数据库有Id 值的记录,您将其设置为Product 对象并返回true,否则返回false

    类似的东西(未测试

    public class Repository: IRepository
    {
        YourDbContext yourDbContext;
        // to do : Initialize yourDbContext via constructor injection
    
        public bool TryGetProduct(int id, out Product product)
        {           
            var p = yourDbContext.Products.FirstOrDefault(a => a.Id == id);
            if (p != null)
            {
                product = p;
                return true;
            }
            product = null;
            return false;
        }
    }
    

    【讨论】:

    • 问题是你失去了控制器操作的异步操作符
    • 因为它有效而且我将使用它,但不幸的是它似乎有一个缺点
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多