2008-11-08 4 views
3

Мы используем хранимые процедуры для для каждого запроса в БД. Это кажется невероятно не- DRY:Как сохранить сохраненные процедуры DRY в C# .NET?

  1. Дизайн стол
  2. Design CRUD операции SPs для этой таблицы
  3. Дизайн кода (предпочтительно класс), чтобы заполнить параметры и выполнить CRUD ПЛов

Если мы добавляем один столбец или изменяем тип данных, мы должны редактировать таблицу, несколько SP и несколько функций в классе внутри .NET.

Каковы рекомендации по сокращению дублирования?

UPDATE:

В сочетании с идеей Винко, я нашел this. Вот немного кода (в C#), что я придумал для тех, кто в ней нуждается:

SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MySQLConnString"].ConnectionString); 
SqlCommand comm = new SqlCommand("NameOfStoredProcedure", conn); 
comm.CommandType = CommandType.StoredProcedure; 

conn.Open(); 
SqlCommandBuilder.DeriveParameters(comm); 
conn.Close(); 

foreach (SqlParameter param in comm.Parameters) 
{ /* do stuff */ } 
+1

Вы могли бы найти это интересно читать перед созданием CRUD хранятся проков для каждой таблицы: HTTP://msdn.microsoft.com/en-us/library/ms978509.aspx – 2008-11-08 05:59:12

ответ

2

Один совет, чтобы избежать модификации, по крайней мере, SP, записывает их, чтобы использовать «интроспекцию», то есть выводить имена столбцов и типы данных из внутренних таблиц или видов информации.

Это сложный код для записи, но он не будет изменять его каждый раз, когда таблица изменяется, и его можно использовать повторно в остальных пакетах SP.

Создайте один SP, который будет описывать таблицы для вас, например, используя временную таблицу (colname varchar, type varchar), которую вы вызовете из остальных SP.

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

2

Я предлагаю использовать инструмент генерации кода, такие как NetTiers для генерации CRUD слоя.

+0

Google для анти-шаблона под названием «YAGNI». – dkretz 2008-11-08 06:06:32

+0

Это ответ на мой ответ? Не могли бы вы возражать? – 2008-11-08 06:17:10

+0

Yup. На практике не каждому столу нужны все четыре операции. И не все таблицы адекватно рассматриваются одним и тем же шаблоном C/R/U/D.Таким образом, вы создаете код, который во многих случаях никогда не будет использоваться (но в любом случае становится частью поддержки). – dkretz 2008-11-08 06:24:53

1

Принципы проектирования ООП предназначены для процедурного кода, а не декларативного кода. В частности, повторное использование SP очень проблематично.

Конструкции пользовательского интерфейса, основанные на генераторах CRUD, хорошо известны. Другой способ явно превратить пользователей в клерков ввода данных. Если вы используете их, убедитесь, что у вас отличный слой абстракции между тем, что они производят, и с тем, с чем приходится сталкиваться пользователям.

Если мы добавим один столбец или изменим тип данных, мы должны отредактировать таблицу, несколько SP и несколько функций в классе в .NET.

Уверенные звуки, как ваш дизайн базы данных диктует ваши требования ООП. Начните с другого направления.

1

Все эти подходы к metaquery умирают на своем пути, как только SQL выходит за пределы одной таблицы. Или хотите вычисленный столбец. Или ...

0

Я не думаю, что это действительно подпадает под руководство DRY. Это просто о настойчивости, и если вы делаете № 3 вручную, вы должны взглянуть на принятие одного из инструментов, которые упрощают это. LINQ to SQL - мой личный фаворит, но их много.

Ваш # 2 может быть легко автоматизирован. Сокращение общей работы, необходимой для: 1) проектирования модели данных (в концепции); 2) реализовать ее на уровне сохранения (создать таблицу или добавить свой столбец); 3) использовать ее на уровне приложения.

1

Лично я не являюсь большим поклонником размещения моего кода запроса в хранимых процедурах. За исключением очень сложных вещей, это просто кажется излишним излишеством.

Вот как я обращаться с моей базы данных и объект падла дизайн:

  1. создать модель данных
  2. создать представление для каждой таблицы
  3. я создаю вставки, обновления & удалить проки для каждого Таблица.
  4. Весь мой код C# указывает на виды и процессы.

Это позволяет мне:

  1. имеет очень гибкую цель запроса (вид)
  2. запроса против взглядов в любой форме, мне нужно без избыточности.
  3. Предотвращение прямого доступа к таблицам с помощью базы данных безопасности
  4. Аннотация модель данных в случае, я когда-нибудь понадобится, чтобы реорганизовать базовую модель данных, не нарушая мой код (я знаю, это может иметь затраты производительности)

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

Я слышал, как люди рекомендуют использовать хранимые процедуры для предотвращения атак SQL Injection, но если вы используете параметризованные запросы при запросе вашего представления, это все равно не будет проблемой. ... и мы всегда используем параметризованные запросы любым способом ... правильно? ;-)

0

Есть несколько таблиц, которые не будут иметь CRUD и не должны быть доступны из вашего приложения и являются артефактами модели реализации базы данных. В частности, к вашим приложениям не следует обращаться к таблицам ссылок «многие ко многим», они должны управляться базой данных с помощью хранимых процедур.

1

Используемый вами подход «DeriveParameters» работает, но включает в себя 2 поездки по базам данных для каждого запроса. При таком подходе будет удар производительности. Блок приложений Microsoft Access Access SqlHelper смягчит это, выполняя ту же самую «интроспекцию», но необязательно кешируя параметры для повторного использования. Это позволит создать единую линию SP вызовы без какой-либо повторяющейся «слизи» Настройка параметров и т.д.

http://msdn.microsoft.com/en-us/library/cc309504.aspx