Передача вызова хранимой процедуры из контекста данных LINQ другому методу. C # - PullRequest
2 голосов
/ 26 февраля 2009

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

Теперь, когда это не так, вот что я хочу сделать. У меня есть контекст данных (.dbml) с множеством хранимых процедур. У меня также есть несколько ситуаций, когда я использую те же самые 20 строк кода для обновления одного столбца в таблице, но единственная разница, отличная от использования другой сетки данных, - это вызов хранимой процедуры. Стремясь уменьшить объем используемого кода, я надеялся на способ передать вызов хранимой процедуры из объекта контекста данных в качестве параметра. Таким образом, я могу переместить весь этот код в одну повторно используемую функцию. Это вообще возможно? Я использую Visual Studio 2008 и C #.

Спасибо за любые рекомендации.

1 Ответ

1 голос
/ 26 февраля 2009

Несмотря на то, что я не могу помочь вам с вещами sql / хранимых процедур, я могу попробовать объяснить делегатов, по крайней мере, с точки зрения C #.

В то время как обычно вы объявляете функции как часть класса (и, следовательно, они сильно привязаны к классу), иногда вы хотите поместить их в переменную. Как только вы это сделаете, вы можете передать его, как и в случае с любой другой переменной.

Итак, мы знаем, что строка - это та переменная, в которую вы вставляете текст. После этого делегат - это тип переменной, в которую вы вставляете functions . Это, однако, очень запутанно, поскольку C # не согласуется и не ясно с тем, как он называет вещи в вашем коде. Обратите внимание:

public void WriteText() {
  Console.WriteLine("Hello");
}

...
Action x = WriteText;
x(); // will invoke the WriteText function

Обратите внимание, что мы используем "Действие", где логика подразумевает, что код должен читать delegate x = WriteText. Причина, по которой нам нужен этот дополнительный беспорядок, заключается в том, что само "делегат" похоже на System.Object. Он не содержит никакой информации, и это своего рода «базовый класс» за всем. Если мы действительно хотим использовать один, мы должны приложить некоторую информацию о Типе. Вот где приходит Action. Определение Action выглядит следующим образом:

public delegate void Action();

Что этот код говорит: «мы объявляем новый делегат с именем Action, , и он не принимает параметров и возвращает void ». После этого, если у вас есть какие-либо функции, которые также не принимают параметров и возвращают void, вы помещаете их в переменные типа Action.

Теперь вы можете вставить обычную функцию в делегат, но вы также можете вставить "анонимную" функцию в делегат. «Анонимная» функция - это то, что вы объявляете встроенным, поэтому вместо того, чтобы присоединять уже объявленную функцию WriteText, мы могли бы создать новую в середине нашего кода следующим образом:

Action x = () => { Console.WriteLine("Hello"); };
x(); // invoke our anonymous function.

То, что это делает, использует "синтаксис лямбды" в C # для объявления новой анонимной функции. Код, который выполняется как часть функции (когда мы ее вызываем): Console.WriteLine.

SO

Чтобы собрать все это вместе, вы можете иметь функцию "SaveData" и передать ее делегату. Он может сделать это 20 строками таблицы, затем передать эту таблицу делегату, и делегат может вызвать соответствующий хранимый процесс. Вот простой пример:

public void SaveData(Action<Table> saveFunc){
    var t = new Table();
    ... 20 lines of code which put stuff into t ...
    saveFunc(t);
}

SaveData( t => StoredProc1.Invoke(t) ); // save using StoredProc1
SaveData( t => StoredProc37.Invoke(t) ); // save using StoredProc37

SO

Сказав ВСЕ ЭТО. Это не то, как я бы на самом деле решил проблему. Вместо передачи делегата в вашу функцию сохраненных данных, было бы более целесообразно, чтобы ваша функция SaveData просто возвращала таблицу, а затем вы могли бы вызывать соответствующий StoredProc без необходимости делегатов вообще

...