Comment créer un objet anonyme avec des noms de propriétés déterminés dynamiquement?

Donné un tableau de valeurs, je voudrais créer un anonyme, un objet avec des propriétés sur la base de ces valeurs. Les noms de propriété serait tout simplement "pN"N est l'indice de la valeur dans le tableau.

Par exemple, étant donné

object[] values = { 123, "foo" };

Je voudrais créer l'objet anonyme

new { p0 = 123, p1 = "foo" };

La seule façon que je peux penser à faire serait d'utiliser un switch ou if de la chaîne jusqu'à un nombre raisonnable de paramètres à l'appui, mais je me demandais si il y avait une façon plus élégante de le faire:

object[] parameterValues = new object[] { 123, "foo" };
dynamic values = null;

switch (parameterValues.Length)
{
    case 1:
        values = new { p0 = parameterValues[0] };
        break;
    case 2:
        values = new { p0 = parameterValues[0], p1 = parameterValues[1] };      
        break;
    //etc. up to a reasonable # of parameters
}

Fond

J'ai déjà un ensemble de méthodes qui exécuter des instructions sql sur une base de données. Les méthodes généralement un string pour l'instruction sql et params object[] pour les paramètres, le cas échéant. La compréhension est que si la requête utilise des paramètres, ils seront nommés @p0, @p1, @p2, etc..

Exemple:

public int ExecuteNonQuery(string commandText, CommandType commandType, params object[] parameterValues) { .... }

qui serait appelé comme ceci:

db.ExecuteNonQuery("insert into MyTable(Col1, Col2) values (@p0, @p1)", CommandType.Text, 123, "foo");

Maintenant je voudrais utiliser Dapper au sein de cette classe d'envelopper et d'exposer Dapper est Query<T> méthode, et de le faire d'une façon qui soit cohérente avec les méthodes existantes, par exemple quelque chose comme:

public IEnumerable<T> ExecuteQuery<T>(string commandText, CommandType commandType, params object[] parameterValues) { .... }

mais Dapper est Query<T> méthode prend les valeurs de paramètre dans un objet anonyme:

var dog = connection.Query<Dog>("select Age = @Age, Id = @Id", new { Age = (int?)null, Id = guid }); 

menant à ma question sur la création de l'objet anonyme de passer des paramètres à Dapper.


L'ajout de code à l'aide de la DynamicParameter classe comme demandé par @Paolo Tedesco.

string sql = "select * from Account where Id = @p0 and username = @p1";
dynamic values = new DynamicParameter(123, "test");
var accounts = SqlMapper.Query<Account>(connection, sql, values);

déclenche une exception à la ligne 581 de Dapper est SqlMapper.cs fichier:

using (var reader = cmd.ExecuteReader())

et à l'exception d'un SqlException:

Doit déclarer la variable scalaire "@p0".

et la vérification de la cmd.Parameters bien montrer aucun paramètre configuré pour la commande.

source d'informationauteur Jeff Ogata