web-dev-qa-db-fra.com

Puis-je mapper un résultat sur Tuple dans Dapper?

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();
26
Tom Gerken

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 .

21
Void Ray

Vous pouvez aimer

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

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.

15
Rubanov

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.

14
Metro Smurf

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();
2
judehall