J'essaie de sélectionner une liste de 2 colonnes entières mapper les résultats à un tuple. À titre d'exemple:
return connection.Query<Tuple<int,int>>("select id1, id2 from sometable").ToList();
ne fonctionne pas, mais la même requête fonctionne si je crée une classe avec deux entiers tels que:
return connection.Query<BogusClass>("select id1, id2 from sometable").ToList();
public class BogusClass{
public int id1 {get;set;}
public int id2 {get;set;}
}
Ma préférence n'est pas d'avoir à créer une classe bidon juste pour obtenir des données avec lesquelles travailler. Dans ce cas, il s'agit de deux colonnes entières, mais il y a d'autres cas d'utilisation auxquels je pourrais penser.
Edit - Answer: C'est la syntaxe qui a fonctionné pour moi HTH
modifié:
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();
Voici un exemple de travail:
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));
}
}
Vous pouvez trouver plus d'exemples ici .
Vous pouvez aimer
string query = "Select value1 as Item1,value2 as Item2 from #sometable";
var data = db.Query<Tuple<int,int>>(query);
Cela fonctionne à partir de C # 7. C'est un 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();
}
Utilisation de la méthode
var item = GetItem(123);
Console.WriteLine($"The publish date of item [{item.Id}] is [{item.PublishDate.Value}]");
Assurez-vous d'avoir installé Dapper 1.50.4 ou une version ultérieure.
Tuple est une option, je préfère utiliser un résultat dynamique chaque fois que je ne veux pas créer de classe, c'est-à-dire
string sql = "Select 'f' as Foo, 'b' as Bar";
var result = connection.Query<dynamic>(sql).Single();
string foo = result.Foo;
string bar = result.Bar
Le nom du champ renvoyé par le résultat sera le nom de la propriété dynamique.
Dans votre cas, vous souhaitez renvoyer une liste et ne pas l'attribuer à des variables uniques, un tuple serait donc plus approprié:
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>>
indique à dapper qu'il y aura deux entiers qui renverront un tuple
* 2 = indique à dapper d'utiliser un Tuple pour renvoyer le résultat
* 3 = indique à dapper que chaque champ retourné est utilisé pour renvoyer un résultat pour chaque propriété du tuple.
* 4 = méthode d'extension Dapper pour convertir le résultat interne de Dapper en List
; par défaut, Dapper renvoie une liste sous les couvertures afin que la distribution soit plus rapide que la copie dans une nouvelle liste.
Pour ceux qui utilisent async, cela peut être réalisé en utilisant 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();