从 dapper 中的多个查询返回可枚举的结果

Posted

技术标签:

【中文标题】从 dapper 中的多个查询返回可枚举的结果【英文标题】:Returning ienumerable result from multiple query in dapper 【发布时间】:2021-09-28 15:27:09 【问题描述】:

我一直在尝试创建使用 dapper 的 QueryMultiple 的方法。我已经设法让多个查询工作,当我调试时,我可以看到数据库中的值被返回。但是,我想在调用 API 时查看 Postman 中的数据。这是问题开始的地方,因为我似乎无法让任何返回类型工作,它几乎总是相同的错误。该错误几乎总是与“无法转换”有关。错误示例如下:

Error   CS1503  Argument 1: cannot convert from 'string' to \RequestRepo.cs 45  Active

Error   CS0266  Cannot implicitly convert type 'System.Collections.Generic.List<string>' to 'System.Collections.Generic.IEnumerable<V4ReactAPI.Models.V4RequestSite.ViewModels.RequestOverview>'. An explicit conversion exists (are you missing a cast?) 90    Active

控制器看起来像:

    [HttpGet]
    public async Task<IActionResult> testa(RequestOverview model)
    

        if (!ModelState.IsValid)
        
            return BadRequest(ModelState);
        
        try
        
            await _request.testa(model);
        
        catch (Exception ex)
        

            return BadRequest(ex.Message);
        
        return Ok();
    

型号:

public class VehicleReg

    public string vehicleRegNr  get; set;  = "";


public class TestIgen

    public string ownerName  get; set;  = "";

(整个模型类的名称是RequestOverview

现在是我自己的类中的方法:

    public async Task<IEnumerable<RequestOverview>> testa(RequestOverview model)
    

        string query = "SELECT TOP 5 RegNumber as vehicleRegNr FROM [dbo].[Vehicle];
        SELECT TOP 5 Name as ownerName FROM [dbo].[Customer];";

        var result = _sqlconnection.QueryMultiple(query);
        var vehicles = result.Read<VehicleReg>();
        var test = result.Read<TestIgen>();
        List<string> allQueries = new List<string>();

        foreach (var item in vehicles)
        
            allQueries.Add(item.vehicleRegNr);
        

        foreach (var item in test)
        
            allQueries.Add(item.ownerName);

        return allQueries.ToList();
    

这会直接抛出一个错误(CS0266 如前所示)。

基本上,我需要以某种方式返回var vehiclesvar test,以便能够在例如在邮递员中调用api时获得要显示的数据。

我也尝试过这种方法,但我再次无法返回数据:

 public async Task<bool> Test()
        

          string query = "SELECT TOP 5 RegNumber as vehicleRegNr FROM [dbo].[Vehicle];
          SELECT TOP 5 Name as ownerName FROM [dbo].[Customer];";

            var result = _sqlconnection.QueryMultiple(query);

            using (var multi = _sqlconnection.QueryMultiple(query, null))
            
              List<VehicleReg> list1 = multi.Read<VehicleReg>().AsList();
              List<TestIgen> list2 = multi.Read<TestIgen>().AsList();
            

            return true;
        

有人对如何返回数据有任何想法吗?

[更新]我尝试了以下方法来避免转换错误,但是当我在 Postman 中尝试时它仍然没有返回任何数据:

public async Task<List<string>> Test()


  string query = "SELECT TOP 5 RegNumber as vehicleRegNr FROM [dbo].[Vehicle];
  SELECT TOP 5 Name as ownerName FROM [dbo].[Customer];";
    List<string> allQueries = new List<string>();
    using (var multi = _sqlconnection.QueryMultiple(query, null))
   
        //List<string> allQueries = new List<string>();
        List<VehicleReg> list1 = multi.Read<VehicleReg>().AsList();
        List<TestIgen> list2 = multi.Read<TestIgen>().AsList();
        //return list1.ToList();
        allQueries.Add(list1.ToString());
        allQueries.Add(list2.ToString());
    
    return allQueries;

【问题讨论】:

RequestOverview 长什么样子? 如错误所述,您尝试返回List&lt;string&gt;,其中testa 方法期望返回IEnumerable&lt;RequestOverview&gt; 的类型 您更新的代码不会成功构建。请简化您的问题 @SelimYildiz 嗯,它为我成功构建了......但基本上,我想使用异步任务(实际上以任何形式,字符串/列表/布尔/ienumerable)和queryMultiple,但我会喜欢从查询中获取结果/数据以在 Postman 中打印,使用更新的代码我可以在调试时看到结果,但在 postman 中它只是返回 200 ok,没有实际数据 看来allQueries.Add(list1.ToString()); allQueries.Add(list2.ToString()); 应该类似于allQueries.AddRange(list1.Select(i=&gt;i.vehicleRegNr).ToList()); allQueries.AddRange(list2.Select(i=&gt;i.ownerName).ToList()); 【参考方案1】:

如果我理解正确,您想返回vehicleRegNrownerName 的列表。所以list1.ToString(); 在这种情况下没有任何意义,因为它是List&lt;VehicleReg&gt; 的一种类型。

在添加到您的 allQueries 之前,您需要 select 字段(vehicleRegNr 来自 VehicleRegownerName 来自 TestIgen)。

所以这个

allQueries.Add(list1.ToString());
allQueries.Add(list2.ToString());

应该是

allQueries.AddRange(list1.Select(i => i.vehicleRegNr));
allQueries.AddRange(list2.Select(i => i.ownerName));

如果你想从 API 返回那个值,你需要使用OK 给定的结果如下:

[HttpGet]
public async Task<IActionResult> testa(RequestOverview model)


    if (!ModelState.IsValid)
    
        return BadRequest(ModelState);
    
    try
    
        return Ok(await _request.testa(model);
    
    catch (Exception ex)
    
        return BadRequest(ex.Message);
    
    return Ok();

见ASP.NET Core return JSON with status code

【讨论】:

非常感谢!更改为 select 并在控制器中的 await 修复它之前简单地添加 return Ok,谢谢!我会接受这个作为答案

以上是关于从 dapper 中的多个查询返回可枚举的结果的主要内容,如果未能解决你的问题,请参考以下文章

获取 dapper.QueryMultiple 方法返回的结果集计数

Dapper 多参数存储过程查询不会从数据库返回任何内容

DB2 - 使用带有字符串数组参数的 Dapper 选择查询将不会返回正确的结果

如何从 Dapper 查询返回 null 而不是 default(T)?

有时 Dapper 或 System.Data 不会为某些数据库(SQL Server 2012 和 2019)上的简单选择查询返回正确的结果

Neo4j,在返回可分页结果的同时查询多个 lucene 索引