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

Tom*_*ken 26 dapper

我试图选择2个整数列的列表将结果映射到元组.举个例子:

return connection.Query<Tuple<int,int>>("select id1, id2 from sometable").ToList();
Run Code Online (Sandbox Code Playgroud)

不起作用,但如果我创建一个具有两个整数的类,相同的查询确实有效,例如:

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

public class BogusClass{
public int id1 {get;set;}
public int id2 {get;set;}
}
Run Code Online (Sandbox Code Playgroud)

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

编辑 - 答案:这是HTH的语法

改变:

return connection.Query<Tuple<int,int>>("select id1, id2 from sometable").ToList();
Run Code Online (Sandbox Code Playgroud)

至:

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

Voi*_*Ray 23

这是一个工作示例:

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));
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以在此处找到更多示例.


小智 19

你可以这样

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

  • Item1,Item2 ......,这就是答案!谢谢! (6认同)

Rub*_*nov 17

这可以从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();
}       
Run Code Online (Sandbox Code Playgroud)

使用方法

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

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


Met*_*urf 14

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

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

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

string foo = result.Foo;
string bar = result.Bar
Run Code Online (Sandbox Code Playgroud)

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

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

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
Run Code Online (Sandbox Code Playgroud)

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

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

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

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


Ale*_*lex 7

决定添加另一个答案,因为我一直看到人们犯这个错误。

是的,但是你可以!请注意,当使用命名元组(又名值元组)时,Dapper 不会注意名称,它会按顺序映射元组。

例如这段代码:

cn.Query<(int ID, int Size)("SELECT Size, ID FROM Table")
Run Code Online (Sandbox Code Playgroud)

将把Size放入IDID放入Size.

再次强调:Dapper 不会查看 valuetuple 名称(这实际上很棒,因为没有反射 - 耶!),但要额外注意