Совет по минимизации параметров хранимой процедуры

У меня есть веб-приложение ASP.NET MVC, которое взаимодействует с базой данных SQL Server 2008 через Entity Framework 4.0.

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

Теперь пользовательский интерфейс имеет около 20 различных вариантов ввода, начиная от текстового поля, раскрывающегося списка, флажков и т. д.

Каждый из этих входов «сгруппирован» в логические разделы.

Пример:

  • Поле поиска: "Фу"
  • Чекбокс A1: отмечен, Чекбокс A2: снят
  • Выпадающий список A: выбран вариант 3
  • Флажок B1: установлен, флажок B2: установлен, флажок B3: снят

Поэтому мне нужно вызвать SPROC следующим образом:

exec SearchPage_FindResults @SearchQuery = 'Foo', @IncludeA1 = 1, @IncludeA2 = 0, @DropDownSelection = 3, @IncludeB1 = 1, @IncludeB2 = 1, @IncludeB3 = 0

Пользовательский интерфейс не слишком важен для этого вопроса - просто хотел дать некоторую перспективу.

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

Теперь мои вопросы/вопросы:

  • Как лучше всего передать эти параметры хранимой процедуре?
  • Существуют ли какие-либо хитрости/новые способы (например, SQL Server 2008) для этого? Специальные "табличные" параметры/массивы - можем ли мы пройти через пользовательские типы? Имейте в виду, что я использую Entity Framework 4.0, но при необходимости всегда могу использовать классический ADO.NET.
  • Как насчет XML? Каковы здесь затраты на сериализацию/десериализацию? Стоит ли оно того?
  • Как насчет параметра для каждого логического раздела? Возможно через запятую? Просто мысли вслух.

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

С учетом сказанного - какой здесь лучший подход?




Ответы (1)


При быстром поиске в Google похоже, что Entity Framework их не поддерживает, но вы можете использовать табличные параметры в ADO.

Вы управляете этим, определяя тип таблицы на своем сервере:

CREATE TYPE yourTypeName AS TABLE (
    columnName <column type>
    -- more columns if you wish, too
)

а затем используйте его, создав SqlCommand и выполнив следующее:

SqlParameter param = command.CreateParameter();
param.ParameterName = "@something"
param.SqlDbType = SqlDbType.Structured
param.Value = // a DataTable which matches your table type, I can stick in code I use if you like
param.TypeName = "table type name";

И ваши процедуры будут выглядеть так:

CREATE PROCEDURE procName
@something yourTypeName READONLY
AS
BEGIN
...

Затем ваши SQL-запросы будут использовать этот параметр, как если бы это была таблица, хотя она доступна только для чтения.

С точки зрения производительности, я не являюсь администратором баз данных и не уверен, насколько быстр XML - я понимаю, что он довольно быстр. Однако TVP невероятно быстры, и даже относительно простой метод DataTable, который я использовал, отлично работает. Подробнее о TVP можно прочитать здесь, и довольно много несколько сообщений в блогах о SQL и TVP в целом.

person Groxx    schedule 04.01.2011
comment
Круто - я пойду с подходом TVP. Спасибо, +1 и принято! - person RPM1984; 04.01.2011