Biorąc pod uwagę tablicę wartości, chciałbym utworzyć anonimowy obiekt z właściwościami opartymi na tych wartościach. Nazwy właściwości będą po prostu "pN"
, gdzie N
jest indeksem wartości w tablicy.Jak utworzyć anonimowy obiekt z nazwami właściwości określonymi dynamicznie?
Na przykład, biorąc pod uwagę
object[] values = { 123, "foo" };
Chciałbym utworzyć obiekt anonimowy
new { p0 = 123, p1 = "foo" };
Jedynym sposobem mogę myśleć to zrobić byłoby używanie switch
lub if
łańcuch do rozsądnej liczby parametrów do obsługi, ale zastanawiałem się, czy był bardziej elegancki sposób to zrobić:
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
}
Tło
Mam istniejący zestaw metod, które wykonują instrukcje SQL przeciwko bazy danych. Metody zwykle pobierają string
dla instrukcji sql i params object[]
dla parametrów, jeśli takie istnieją. Rozumie się, że jeśli zapytanie używa parametrów, będą one nazywane @p0, @p1, @p2, etc.
.
Przykład:
public int ExecuteNonQuery(string commandText, CommandType commandType, params object[] parameterValues) { .... }
które można nazwać tak:
db.ExecuteNonQuery("insert into MyTable(Col1, Col2) values (@p0, @p1)", CommandType.Text, 123, "foo");
Teraz chciałbym użyć Dapper w tej klasie do zawijania i narazić Query<T>
metodę Wytworny, a zrobić to w sposób sposób zgodny z istniejącymi metodami, np coś takiego:
public IEnumerable<T> ExecuteQuery<T>(string commandText, CommandType commandType, params object[] parameterValues) { .... }
ale Query<T>
metoda Dapper przybiera wartości parametrów w anonimowej obiektu:
var dog = connection.Query<Dog>("select Age = @Age, Id = @Id", new { Age = (int?)null, Id = guid });
prowadzące do mojego pytania na temat tworzenia anonimowego obiekt przekazać parametry do Dapper.
Dodawanie kodu przy użyciu klasy DynamicParameter
wymagane przez @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);
zgłasza wyjątek w linii 581 pliku SqlMapper.cs Dapper za:
using (var reader = cmd.ExecuteReader())
i wyjątek jest SqlException
:
Musi zadeklarować zmienną skalarne "@ p0".
i sprawdzanie właściwości cmd.Parameters
nie wykazują parametrów skonfigurowanych dla polecenia.
Tak, niewłaściwie używasz DynamicParameter, patrz wiersz 243: http://code.google.com/p/dapper-dot-net/source/browse/Tests/Tests.cs –
również, 'IDynamicParamters' zapewnia absolutną elastyczność. Jeśli chodzi o korzyści dla dapperów, nigdy nie powinieneś potrzebować pieczenia typów anonowych, jako doświadczenia w nauce, które możesz, ale nie jest to warte wysiłku. W szczególności możesz wypalić silny typ z ICollection, jeśli naprawdę chcesz używać emisji. –