Хранимые процедуры дизайнера CUD

В этом пошаговом руководстве показано, как сопоставить операции create\insert, update и delete (CUD) типа сущности с хранимыми процедурами с помощью конструктора Entity Framework (EF Designer).  По умолчанию Entity Framework автоматически создает инструкции SQL для операций CUD, но вы также можете сопоставить хранимые процедуры с этими операциями.  

Обратите внимание, что Code First не поддерживает сопоставление хранимых процедур или функций. Однако можно вызывать хранимые процедуры или функции с помощью метода System.Data.Entity.DbSet.SqlQuery. Рассмотрим пример.

var query = context.Products.SqlQuery("EXECUTE [dbo].[GetAllProducts]");

Рекомендации при сопоставлении операций CUD с хранимыми процедурами

При сопоставлении операций CUD с хранимыми процедурами применяются следующие рекомендации.

  • Если вы сопоставляете одну из операций CUD с хранимой процедурой, сопоставите все из них. Если вы не сопоставляете все три, не сопоставленные операции завершатся ошибкой, если выполнены, и будет выброшено исключение UpdateException.
  • Необходимо сопоставить каждый параметр хранимой процедуры с свойствами сущности.
  • Если сервер создает значение первичного ключа для вставленной строки, необходимо сопоставить это значение с свойством ключа сущности. В следующем примере хранимая процедура InsertPerson возвращает только что созданный первичный ключ в составе результирующего набора этой процедуры. Первичный ключ сопоставляется с ключом сущности (PersonID) с помощью <функции добавления привязок> результатов конструктора EF.
  • Вызовы хранимых процедур сопоставляются один к одному с сущностями в концептуальной модели. Например, если вы реализуете иерархию наследования в концептуальной модели, а затем сопоставляете хранимые процедуры CUD для родительских (базовых) и дочерних (производных) сущностей, сохранение изменений в дочерних сущностях будет вызывать только хранимые процедуры дочернего, это не вызовет запуск хранимых процедур родительского элемента.

Необходимые условия

Для выполнения данного пошагового руководства необходимо выполнить следующие действия.

Настройка проекта

  • Откройте Visual Studio 2012.
  • Выберите Файл -> Новый -> Проект
  • В левой области щелкните Visual C#, а затем выберите шаблон консоли .
  • Введите CUDSProcsSample в качестве имени.
  • Нажмите ОК.

Создание модели

  • Щелкните правой кнопкой мыши имя проекта в обозревателе решений и выберите "Добавить -> Новый элемент".

  • Выберите данные из меню слева и выберите ADO.NET модель данных сущности в области шаблонов.

  • Введите CUDSProcs.edmx для имени файла и нажмите кнопку "Добавить".

  • В диалоговом окне "Выбор содержимого модели" выберите "Создать из базы данных" и нажмите кнопку "Далее".

  • Нажмите кнопку "Создать подключение". В диалоговом окне "Свойства подключения" введите имя сервера (например, (localdb)\mssqllocaldb), выберите метод проверки подлинности, введите School для имени базы данных и нажмите кнопку "ОК". Диалоговое окно "Выбор подключения к данным" обновляется с помощью параметра подключения к базе данных.

  • В диалоговом окне "Выбор объектов базы данных" в узле "Таблицы " выберите таблицу Person .

  • Кроме того, выберите следующие хранимые процедуры в узле хранимых процедур и функций : DeletePerson, InsertPerson и UpdatePerson.

  • Начиная с Visual Studio 2012 конструктор EF поддерживает массовый импорт хранимых процедур. Импорт выбранных хранимых процедур и функций в модель сущностей проверяется по умолчанию. Так как в этом примере у нас есть хранимые процедуры, которые вставляют, обновляют и удаляют типы сущностей, мы не хотим импортировать их и снимите этот флажок.

    Импорт S Procs

  • Нажмите кнопку "Готово". Отображается конструктор EF, предоставляющий рабочую область для редактирования вашей модели.

Сопоставьте сущность Person с хранимыми процедурами

  • Щелкните правой кнопкой мыши тип сущности Person и выберите "Сопоставление хранимых процедур".

  • Сопоставления хранимых процедур отображаются в окне сведений о сопоставлении .

  • Нажмите <"Вставка функции">. Поле становится раскрывающимся списком хранимых процедур в модели хранения, которые можно сопоставить с типами сущностей в концептуальной модели. Выберите InsertPerson в раскрывающемся списке.

  • Отображаются сопоставления по умолчанию между параметрами хранимой процедуры и свойствами сущности. Обратите внимание, что стрелки указывают направление сопоставления: значения свойств предоставляются параметрам хранимой процедуры.

  • Нажмите кнопку <"Добавить привязку> результата".

  • Введите NewPersonID, имя параметра, возвращаемого хранимой процедурой InsertPerson . Не следует вводить начальные или конечные пробелы.

  • Нажмите клавишу ВВОД.

  • По умолчанию NewPersonID сопоставляется с ключом сущности PersonID. Обратите внимание, что стрелка указывает направление сопоставления: значение столбца результатов предоставляется свойству.

    Сведения о сопоставлении

  • Щелкните <"Выбрать функцию> обновления" и выберите UpdatePerson в результирующем раскрывающемся списке.

  • Отображаются сопоставления по умолчанию между параметрами хранимой процедуры и свойствами сущности.

  • Нажмите кнопку <"Удалить функцию> " и выберите DeletePerson из результирующего раскрывающегося списка.

  • Отображаются сопоставления по умолчанию между параметрами хранимой процедуры и свойствами сущности.

Операции вставки, обновления и удаления типа сущности Person теперь сопоставляются с хранимыми процедурами.

Если вы хотите включить проверку параллелизма при обновлении или удалении сущности с хранимыми процедурами, используйте один из следующих параметров:

  • Используйте параметр OUTPUT , чтобы вернуть количество затронутых строк из хранимой процедуры и установить флажок "Затронутые строки " рядом с именем параметра. Если возвращаемое значение равно нулю при вызове операции, будет брошено OptimisticConcurrencyException.
  • Установите флажок "Использовать исходное значение " рядом с свойством, которое вы хотите использовать для проверки параллелизма. При попытке обновления значение свойства, которое изначально было прочитано из базы данных, будет использоваться при записи данных обратно в базу данных. Если значение не совпадает со значением в базе данных, будет выброшено OptimisticConcurrencyException.

Используйте модель

Откройте файл Program.cs , в котором определен метод Main . Добавьте следующий код в функцию Main.

Код создает новый объект Person , а затем обновляет объект и, наконец, удаляет объект.

    using (var context = new SchoolEntities())
    {
        var newInstructor = new Person
        {
            FirstName = "Robyn",
            LastName = "Martin",
            HireDate = DateTime.Now,
            Discriminator = "Instructor"
        }

        // Add the new object to the context.
        context.People.Add(newInstructor);

        Console.WriteLine("Added {0} {1} to the context.",
            newInstructor.FirstName, newInstructor.LastName);

        Console.WriteLine("Before SaveChanges, the PersonID is: {0}",
            newInstructor.PersonID);

        // SaveChanges will call the InsertPerson sproc.  
        // The PersonID property will be assigned the value
        // returned by the sproc.
        context.SaveChanges();

        Console.WriteLine("After SaveChanges, the PersonID is: {0}",
            newInstructor.PersonID);

        // Modify the object and call SaveChanges.
        // This time, the UpdatePerson will be called.
        newInstructor.FirstName = "Rachel";
        context.SaveChanges();

        // Remove the object from the context and call SaveChanges.
        // The DeletePerson sproc will be called.
        context.People.Remove(newInstructor);
        context.SaveChanges();

        Person deletedInstructor = context.People.
            Where(p => p.PersonID == newInstructor.PersonID).
            FirstOrDefault();

        if (deletedInstructor == null)
            Console.WriteLine("A person with PersonID {0} was deleted.",
                newInstructor.PersonID);
    }
  • Скомпилируйте и запустите приложение. Программа создает следующие выходные данные *

Замечание

PersonID создается автоматически сервером, поэтому вы, скорее всего, увидите другое число*

Added Robyn Martin to the context.
Before SaveChanges, the PersonID is: 0
After SaveChanges, the PersonID is: 51
A person with PersonID 51 was deleted.

Если вы работаете с конечной версией Visual Studio, вы можете использовать Intellitrace с отладчиком, чтобы просмотреть инструкции SQL, которые выполняются.

Отладка с помощью Intellitrace