我可以将结果映射到 Dapper 中的元组吗?
Can I map a result to Tuple in Dapper?
我正在尝试 select 两个整数列的列表将结果映射到 Tuple<int,int>
。例如:
connection.Query<Tuple<int, int>>("select id1, id2 from sometable").ToList();
不起作用,但如果我用两个整数创建 class,则相同的查询会起作用,例如:
public class BogusClass {
public int id1 { get; set; }
public int id2 { get; set; }
}
connection.Query<BogusClass>("select id1, id2 from sometable").ToList();
我的偏好是不必创建一些伪造的 class 只是为了获取一些数据。在这种情况下,它是两个整数列,但还有其他我能想到的用例。
编辑: 我通过更改
解决了这个问题
connection.Query<Tuple<int, int>>("select id1, id2 from sometable").ToList();
至
connection.Query<int, int, Tuple<int, int>>("select id1, id2 from sometable", Tuple.Create, splitOn: "*").ToList();
这是一个工作示例:
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));
}
}
元组是一种选择,我更喜欢在不想创建 class 时使用动态结果,即
string sql = "Select 'f' as Foo, 'b' as Bar";
var result = connection.Query<dynamic>(sql).Single();
string foo = result.Foo;
string bar = result.Bar
从结果中 return 得到的字段名称将是动态 属性 的名称。
在你的情况下,你想要 return 一个列表而不是分配给单个变量,所以元组更合适:
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 将有两个整数 return 一个元组
*2 = 告诉 dapper 使用元组来 return 结果
*3 = 告诉 dapper 每个字段 returned 用于 return 元组的每个 属性 的结果。
*4 = Dapper 扩展方法将 Dapper 的内部结果转换为 List
;默认情况下,Dapper return 隐藏了一个列表,因此转换比复制到新列表更快。
你可以这样
string query = "Select value1 as Item1,value2 as Item2 from #sometable";
var data = db.Query<Tuple<int,int>>(query);
这从 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 或更高版本。
对于那些使用异步的,这可以通过使用 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();
这在 .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
}
}
我正在尝试 select 两个整数列的列表将结果映射到 Tuple<int,int>
。例如:
connection.Query<Tuple<int, int>>("select id1, id2 from sometable").ToList();
不起作用,但如果我用两个整数创建 class,则相同的查询会起作用,例如:
public class BogusClass {
public int id1 { get; set; }
public int id2 { get; set; }
}
connection.Query<BogusClass>("select id1, id2 from sometable").ToList();
我的偏好是不必创建一些伪造的 class 只是为了获取一些数据。在这种情况下,它是两个整数列,但还有其他我能想到的用例。
编辑: 我通过更改
解决了这个问题connection.Query<Tuple<int, int>>("select id1, id2 from sometable").ToList();
至
connection.Query<int, int, Tuple<int, int>>("select id1, id2 from sometable", Tuple.Create, splitOn: "*").ToList();
这是一个工作示例:
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));
}
}
元组是一种选择,我更喜欢在不想创建 class 时使用动态结果,即
string sql = "Select 'f' as Foo, 'b' as Bar";
var result = connection.Query<dynamic>(sql).Single();
string foo = result.Foo;
string bar = result.Bar
从结果中 return 得到的字段名称将是动态 属性 的名称。
在你的情况下,你想要 return 一个列表而不是分配给单个变量,所以元组更合适:
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 将有两个整数 return 一个元组
*2 = 告诉 dapper 使用元组来 return 结果
*3 = 告诉 dapper 每个字段 returned 用于 return 元组的每个 属性 的结果。
*4 = Dapper 扩展方法将 Dapper 的内部结果转换为 List
;默认情况下,Dapper return 隐藏了一个列表,因此转换比复制到新列表更快。
你可以这样
string query = "Select value1 as Item1,value2 as Item2 from #sometable";
var data = db.Query<Tuple<int,int>>(query);
这从 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 或更高版本。
对于那些使用异步的,这可以通过使用 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();
这在 .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
}
}