我可以将结果映射到Dapper中的Tuple吗?

时间:2016-01-19 02:12:02

标签: dapper

我试图选择2个整数列的列表将结果映射到元组。仅作为一个例子:

return connection.Query<Tuple<int,int>>("select id1, id2 from sometable").ToList();

不起作用,但是如果我创建一个包含两个整数的类,例如:

,则相同的查询会起作用
return connection.Query<BogusClass>("select id1, id2 from sometable").ToList();

public class BogusClass{
public int id1 {get;set;}
public int id2 {get;set;}
}

我的偏好不是为了获得一些数据而必须创建一些虚假类。在这种情况下,它是两个整数列,但我还能想到其他用例。

编辑 - 答案: 这是对我有用的语法HTH

改变:

return connection.Query<Tuple<int,int>>("select id1, id2 from sometable").ToList();

为:

return connection.Query<int, int, Tuple<int, int>>("select id1, id2 from sometable", Tuple.Create, splitOn: "*").ToList();

6 个答案:

答案 0 :(得分:20)

这是一个有效的例子:

public class DapperTests
{
    [Test]
    public void TuppleTest()
    {
        var conn = new SqlConnection(@"Data Source=.\sqlexpress; Integrated Security=true; Initial Catalog=mydb");
        conn.Open();

        var result = conn.Query<int, int, Tuple<int, int>>(
            "select 1,2 union all select 4,5", Tuple.Create, splitOn: "*").ToList();

        conn.Close();

        Assert.That(result.Count, Is.EqualTo(2));
    }
}

您可以找到更多示例here

答案 1 :(得分:13)

元组是一种选择,每当我不想创建一个类时,我更喜欢使用动态结果,即

string sql = "Select 'f' as Foo, 'b' as Bar";

var result = connection.Query<dynamic>(sql).Single();

string foo = result.Foo;
string bar = result.Bar

从结果返回的字段名称将是动态属性的名称。

在您的情况下,您希望返回一个列表而不是分配给单个变量,因此元组更合适:

string sql = "select id1, id2 from sometable";

List<Tuple<int, int>> result = conn.Query<int, int, Tuple<int, int>>( // *1
    sql,
    Tuple.Create, // *2
    splitOn: "*" ) // *3
    .AsList(); // *4

* 1 = <int,int, Tuple<int, int>>告诉dapper将会有两个将返回元组的整数

* 2 =告诉dapper使用Tuple返回结果

* 3 =告诉dapper返回的每个字段用于返回元组的每个属性的结果。

* 4 = Dapper扩展方法将Dapper的内部结果强制转换为List;默认情况下,Dapper会在封面下返回一个列表,因此强制转换比复制到新列表要快。

答案 2 :(得分:13)

这可以从C#7开始。这是Value Tuple

public (int Id, DateTime? PublishDate) GetItem(string id)
{
    const string sqlCommand = "select top 1 Id, PublishDate from Item where Id = @id";

    return _connection.Query<(int, DateTime?)>(sqlCommand, new { id }).FirstOrDefault();
}       

使用方法

var item = GetItem(123);
Console.WriteLine($"The publish date of item [{item.Id}] is [{item.PublishDate.Value}]");

确保已安装Dapper 1.50.4或更高版本。

答案 3 :(得分:12)

你可以这样

string query = "Select value1 as Item1,value2 as Item2 from #sometable";
var data = db.Query<Tuple<int,int>>(query);

答案 4 :(得分:1)

对于使用异步的用户,可以使用ValueTuple来实现。

var res = await conn.QueryAsync<(int Id1, int Id2)>(sql);

List<Tuple<int, int>> tuples = res.Select(x => new Tuple<int, int>(x.Id1, x.Id2)).ToList();

答案 5 :(得分:0)

这在 .NET Core 3.1 中对我有用

string sql = "SELECT UserAcctId, MinAge, MaxAge FROM [MemberDetails]";

using IDbConnection dbConnection = new SqlConnection(_connectionString);
dbConnection.Open();

var results = dbConnection.Query<(int userAcctId, short minAge,  short maxAge)>(sql);
foreach (var item in results) {
   if (item.minAge > 0) { 
    // do something
   }
}