C #: передача параметров в функцию через массив двумерных объектов - PullRequest
2 голосов
/ 30 сентября 2011

Я пытаюсь написать аккуратный маленький универсальный метод Sql, который будет принимать SQL-запрос и список параметров и возвращать результат.Я хочу, чтобы он был достаточно аккуратным, чтобы я мог вызывать его одной строкой из любого другого кода.

Есть ли какой-нибудь действительно изящный способ сделать это?Я не хочу создавать все SqlParameters в вызывающем коде, и я не хочу передавать и разбивать строку.В прошлом я использовал массив string [] и принимал каждый нечетный член в качестве имени параметра, а каждый четный - в качестве значения параметра, но это слишком легко испортить при вызове метода.

В идеале я бы хотел сделать именно это:

Data.SQL("Select * from Table where my_id = @my_id", { my_id = 1 });

Я знаю, что это немного нереально, поэтому я попробовал это:

Data.SQL("Select * from Table where my_id = @my_id", new Object[,]{ { "my_id", 1 } });

Однако, когда я пытаюсьи обрабатывать это на другом конце, я получаю только неприятности:

public static Object SQL(String command, Object[,] parameters = null){
     [ ... reusable SQL code here... ] 

     foreach(Object[] p in parameters){
            cmd.Parameters.Add(new SqlParameter(p[0].ToString(), p[1].ToString());
     }
}

выглядит хорошо, но выдает ошибку в операторе foreach

foreach (Object[] p in parameters)

Невозможнодля приведения объекта типа 'System.String' к типу 'System.Object []'

Но я не передал это массив System.String,То, что я передал , было 2D System.Object []!Не так ли?

Может быть, это просто небольшая проблема с кодом, что-то глупое, я делаю неправильно.Обычно это так.Но я полагаю, что вы, ребята, знаете какой-то еще более изящный способ сделать все это.

1 Ответ

4 голосов
/ 30 сентября 2011

В идеале я бы хотел сделать именно это:

Data.SQL("Select * from Table where my_id = @my_id", { my_id = 1 });

Я знаю, что это немного нереально,

Ну, в точно этой формы, да ... но попробуйте вместо этого:

Data.SQL("Select * from Table where my_id = @my_id", new { my_id = 1 });

Это будет использовать анонимный тип для аргумента, который вы можете исследовать с помощью отражения. Вероятно, вам нужен только один параметр (т.е. это будет SQL(string sql, object parameters)), потому что вы передадите несколько параметров в один объект:

Data.SQL("Select * from Table where my_id = @my_id and name = @name",
         new { my_id = 1, name = "Jon" });

Больше альтернатив:

  • Если вы используете C # 4, динамическая типизация может оказаться полезной; посмотрите, что, например, Massive делает.
  • Как упомянул Рэй, вы можете передать в Dictionary<string, object>; опять же, C # 3 делает это проще, чем иначе:

    Data.SQL("...", new Dictionary<string, object> { 
             { "my_id", 1 },
             { "name", "Jon" }});
    

РЕДАКТИРОВАТЬ: Что касается точной проблемы, с которой вы сталкиваетесь: вам необходимо понять разницу между прямоугольным массивом (например, Object[,]) и зубчатым массивом (например, Object[][]). Последний представляет собой массив массивов, который используется для использования параметра, но на самом деле это только прямоугольный массив. Изменение типа параметра на Object[][] вполне может решить эту непосредственную проблему - но лично я перейду к одному из подходов, описанных выше. Кстати, я бы даже попытался избежать превращения всего в строку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...