Поделиться через


Расширенные сценарии Entity Framework для веб-приложения MVC (10 из 10)

Том Дайкстра

Пример веб-приложения Contoso University демонстрирует создание ASP.NET приложений MVC 4 с помощью Entity Framework 5 Code First и Visual Studio 2012. Сведения о серии руководств см. в первом руководстве серии.

Примечание.

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

В предыдущем руководстве вы реализовали репозиторий и единицы рабочих шаблонов. В этом руководстве рассматриваются следующие темы:

  • Выполнение необработанных запросов SQL.
  • Выполнение запросов без отслеживания.
  • Изучение запросов, отправленных в базу данных.
  • Работа с классами прокси-сервера.
  • Отключение автоматического обнаружения изменений.
  • Отключение проверки при сохранении изменений.
  • Ошибки и обходные проблемы

Для большинства этих разделов вы будете работать с уже созданными страницами. Чтобы использовать необработанный SQL для выполнения массовых обновлений, вы создадите новую страницу, которая обновляет количество кредитов всех курсов в базе данных:

Снимок экрана: начальная страница

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

Снимок экрана: страница редактирования отдела университета Contoso с повторяющимся сообщением об ошибке администратора.

Выполнение необработанных запросов SQL

Первый API Entity Framework Code включает методы, позволяющие передавать команды SQL непосредственно в базу данных. Вам доступны следующие варианты:

  • Использование метода DbSet.SqlQuery для запросов, которые возвращают типы сущностей. Возвращаемые объекты должны иметь тип, ожидаемый DbSet объектом, и они автоматически отслеживаются контекстом базы данных, если вы не отключите отслеживание. (См. следующий раздел о методе AsNoTracking .)
  • Database.SqlQuery Используйте метод для запросов, возвращающих типы, которые не являются сущностями. Возвращаемые данные не отслеживаются контекстом базы данных, даже если вы используете этот метод для извлечения типов сущностей.
  • Используйте Database.ExecuteSqlCommand для команд, отличных от запросов.

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

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

Вызов запроса, возвращающего сущности

Предположим, вы хотите GenericRepository , чтобы класс предоставлял дополнительную гибкость фильтрации и сортировки, не требуя создания производного класса с дополнительными методами. Один из способов добиться этого — добавить метод, который принимает SQL-запрос. Затем можно указать любой тип фильтрации или сортировки в контроллере, например Where предложение, зависящее от соединений или вложенных запросов. В этом разделе вы узнаете, как реализовать такой метод.

GetWithRawSql Создайте метод, добавив следующий код в GenericRepository.cs:

public virtual IEnumerable<TEntity> GetWithRawSql(string query, params object[] parameters)
{
    return dbSet.SqlQuery(query, parameters).ToList();
}

В CourseController.cs вызовите новый метод из Details метода, как показано в следующем примере:

public ActionResult Details(int id)
{
    var query = "SELECT * FROM Course WHERE CourseID = @p0";
    return View(unitOfWork.CourseRepository.GetWithRawSql(query, id).Single());
}

В этом случае можно было бы использовать GetByID метод, но вы используете GetWithRawSql этот метод, чтобы убедиться, что GetWithRawSQL метод работает.

Запустите страницу сведений, чтобы проверить, работает ли запрос на выбор (выберите вкладку "Курс " и " Сведения " для одного курса).

Снимок экрана: страница сведений о университете Contoso.

Вызов запроса, возвращающего другие типы объектов

Ранее вы создали таблицу статистики учащихся на странице сведений, в которой было показано число учащихся на каждую дату регистрации. Код, который делает это в HomeController.cs использует LINQ:

var data = from student in db.Students
           group student by student.EnrollmentDate into dateGroup
           select new EnrollmentDateGroup()
           {
               EnrollmentDate = dateGroup.Key,
               StudentCount = dateGroup.Count()
           };

Предположим, вы хотите написать код, который извлекает эти данные непосредственно в SQL, а не с помощью LINQ. Для этого необходимо выполнить запрос, возвращающий что-то другое, отличное от объектов сущностей, что означает, что необходимо использовать Database.SqlQuery метод.

В HomeController.cs замените инструкцию LINQ в About методе следующим кодом:

var query = "SELECT EnrollmentDate, COUNT(*) AS StudentCount "
    + "FROM Person "
    + "WHERE EnrollmentDate IS NOT NULL "
    + "GROUP BY EnrollmentDate";
var data = db.Database.SqlQuery<EnrollmentDateGroup>(query);

Запустите страницу "О программе". На экран будут выведены те же данные, что и ранее.

Снимок экрана: страница

Вызов запроса обновления

Предположим, что администраторы Университета Contoso хотят иметь возможность выполнять массовые изменения в базе данных, например изменение количества кредитов для каждого курса. Поскольку в университете ведется множество курсов, будет неэффективно извлекать их в виде сущностей и изменять по отдельности. В этом разделе вы реализуете веб-страницу, которая позволяет пользователю указать фактор, с помощью которого можно изменить количество кредитов для всех курсов, и вы будете вносить изменения, выполнив инструкцию SQL UPDATE . Веб-страница должна выглядеть так, как показано на следующем рисунке:

Снимок экрана: начальная страница

В предыдущем руководстве вы использовали универсальный репозиторий для чтения и обновления Course сущностей в контроллере Course . Для этой операции массового обновления необходимо создать новый метод репозитория, который не используется в универсальном репозитории. Для этого вы создадите выделенный CourseRepository класс, производный от GenericRepository класса.

В папке DAL создайте CourseRepository.cs и замените существующий код следующим кодом:

using System;
using ContosoUniversity.Models;

namespace ContosoUniversity.DAL
{
    public class CourseRepository : GenericRepository<Course>
    {
        public CourseRepository(SchoolContext context)
            : base(context)
        {
        }

        public int UpdateCourseCredits(int multiplier)
        {
            return context.Database.ExecuteSqlCommand("UPDATE Course SET Credits = Credits * {0}", multiplier);
        }

    }
}

В UnitOfWork.cs измените Course тип репозитория на GenericRepository<Course>CourseRepository:

private CourseRepository courseRepository;
public CourseRepository CourseRepository
{
    get
    {

        if (this.courseRepository == null)
        {
            this.courseRepository = new CourseRepository(context);
        }
        return courseRepository;
    }
}

В CourseController.cs добавьте UpdateCourseCredits метод:

public ActionResult UpdateCourseCredits(int? multiplier)
{
    if (multiplier != null)
    {
        ViewBag.RowsAffected = unitOfWork.CourseRepository.UpdateCourseCredits(multiplier.Value);
    }
    return View();
}

Этот метод будет использоваться для обоих HttpGet и HttpPost. HttpGet UpdateCourseCredits При выполнении метода переменная будет иметь значение NULL, multiplier а представление отобразит пустое текстовое поле и кнопку отправки, как показано на предыдущем рисунке.

При нажатии кнопки "Обновить" и HttpPost выполнении multiplier метода в текстовом поле будет введено значение. Затем код вызывает метод репозитория UpdateCourseCredits , который возвращает количество затронутых строк и это значение хранится в объекте ViewBag . Когда представление получает количество затронутых строк в ViewBag объекте, оно отображает это число вместо текстового поля и кнопки отправки, как показано на следующем рисунке:

Снимок экрана, на котором показана затронутая страница

Создайте представление в папке Views\Course для страницы "Обновить кредиты курса":

Снимок экрана: диалоговое окно

В Views\Course\UpdateCourseCredits.cshtml замените код шаблона следующим кодом:

@model ContosoUniversity.Models.Course

@{
    ViewBag.Title = "UpdateCourseCredits";
}

<h2>Update Course Credits</h2>

@if (ViewBag.RowsAffected == null)
{
    using (Html.BeginForm())
    {
        <p>
            Enter a number to multiply every course's credits by: @Html.TextBox("multiplier")
        </p>
        <p>
            <input type="submit" value="Update" />
        </p>
    }
}
@if (ViewBag.RowsAffected != null)
{
    <p>
        Number of rows updated: @ViewBag.RowsAffected
    </p>
}
<div>
    @Html.ActionLink("Back to List", "Index")
</div>

Выполните метод UpdateCourseCredits, выбрав вкладку Courses (Курсы), а затем добавив "/UpdateCourseCredits" в конец URL-адреса в адресной строке браузера (например, http://localhost:50205/Course/UpdateCourseCredits). Введите число в текстовое поле:

Снимок экрана: начальная страница

Нажмите Обновить. Отобразится число обработанных строк:

Снимок экрана: страница

Нажмите кнопку Back to List (Вернуться к списку), чтобы просмотреть список курсов с измененным числом зачетных баллов.

Снимок экрана: страница индекса курсов. Список курсов отображается с измененным числом кредитов.

Дополнительные сведения о необработанных запросах SQL см . в блоге группы Entity Framework в необработанных SQL-запросах .

и без отслеживания

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

Можно указать, отслеживает ли контекст объекты сущности для запроса с помощью AsNoTracking метода. Как правило, это требуется в следующих сценариях:

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

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

В DepartmentController.cs добавьте новый метод, который можно вызвать из Edit и Create методов, чтобы убедиться, что два отдела не имеют одного администратора:

private void ValidateOneAdministratorAssignmentPerInstructor(Department department)
{
    if (department.PersonID != null)
    {
        var duplicateDepartment = db.Departments
            .Include("Administrator")
            .Where(d => d.PersonID == department.PersonID)
            .FirstOrDefault();
        if (duplicateDepartment != null && duplicateDepartment.DepartmentID != department.DepartmentID)
        {
            var errorMessage = String.Format(
                "Instructor {0} {1} is already administrator of the {2} department.",
                duplicateDepartment.Administrator.FirstMidName,
                duplicateDepartment.Administrator.LastName,
                duplicateDepartment.Name);
            ModelState.AddModelError(string.Empty, errorMessage);
        }
    }
}

Добавьте код в try блок HttpPost Edit метода, чтобы вызвать этот новый метод, если ошибки проверки отсутствуют. Блок try теперь выглядит следующим образом:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(
   [Bind(Include = "DepartmentID, Name, Budget, StartDate, RowVersion, PersonID")]
    Department department)
{
   try
   {
      if (ModelState.IsValid)
      {
         ValidateOneAdministratorAssignmentPerInstructor(department);
      }

      if (ModelState.IsValid)
      {
         db.Entry(department).State = EntityState.Modified;
         db.SaveChanges();
         return RedirectToAction("Index");
      }
   }
   catch (DbUpdateConcurrencyException ex)
   {
      var entry = ex.Entries.Single();
      var clientValues = (Department)entry.Entity;

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

Снимок экрана: страница редактирования отдела с повторяющимся сообщением об ошибке администратора.

Теперь снова запустите страницу редактирования отдела и на этот раз измените сумму бюджета . При нажатии кнопки "Сохранить" отображается страница ошибки:

Снимок экрана: страница

Сообщение об ошибке исключения — "An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key." Это произошло из-за следующей последовательности событий:

  • Метод Edit вызывает ValidateOneAdministratorAssignmentPerInstructor метод, который извлекает все отделы, имеющие Ким Аберкромби в качестве администратора. Это приводит к чтению английского отдела. Так как это отдел редактируется, сообщение об ошибке не сообщается. Однако в результате этой операции чтения сущность английского отдела, считываемая из базы данных, теперь отслеживается контекстом базы данных.
  • Метод Edit пытается задать Modified флаг для сущности английского отдела, созданной привязкой модели MVC, но это завершается ошибкой, так как контекст уже отслеживает сущность для английского отдела.

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

В DepartmentController.cs в методе ValidateOneAdministratorAssignmentPerInstructor не укажите отслеживание, как показано в следующем примере:

var duplicateDepartment = db.Departments
   .Include("Administrator")
   .Where(d => d.PersonID == department.PersonID)
   .AsNoTracking()
   .FirstOrDefault();

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

Изучение запросов, отправленных в базу данных

В некоторых случаях полезно иметь возможность просмотреть фактические SQL-запросы, отправляемые в базу данных. Для этого можно проверить переменную запроса в отладчике или вызвать метод запроса ToString . Чтобы попробовать это, вы посмотрите на простой запрос, а затем посмотрите, что происходит с ним при добавлении параметров, таких охотной загрузки, фильтрации и сортировки.

В Controllers/CourseController замените Index метод следующим кодом:

public ViewResult Index()
{
    var courses = unitOfWork.CourseRepository.Get();
    return View(courses.ToList());
}

Теперь установите точку останова в GenericRepository.cs в return query.ToList(); инструкциях return orderBy(query).ToList(); Get метода. Запустите проект в режиме отладки и выберите страницу индекса курса. Когда код достигает точки останова, изучите query переменную. Отобразится запрос, отправляемый в SQL Server. Это простая Select инструкция:

{SELECT 
[Extent1].[CourseID] AS [CourseID], 
[Extent1].[Title] AS [Title], 
[Extent1].[Credits] AS [Credits], 
[Extent1].[DepartmentID] AS [DepartmentID]
FROM [Course] AS [Extent1]}

Снимок экрана, на котором показана вкладка универсального репозитория веб-приложения. Выбрана переменная запроса.

Запросы могут быть слишком длинными для отображения в окнах отладки в Visual Studio. Чтобы просмотреть весь запрос, можно скопировать значение переменной и вставить его в текстовый редактор:

Снимок экрана: значение переменной с раскрывающимся меню, отображаемое при выборе. Выделен параметр

Теперь вы добавите раскрывающийся список на страницу индекса курса, чтобы пользователи могли фильтровать для определенного отдела. Вы отсортируете курсы по названию, и вы укажетесь для свойства Department навигации. В CourseController.cs замените Index метод следующим кодом:

public ActionResult Index(int? SelectedDepartment)
{
    var departments = unitOfWork.DepartmentRepository.Get(
        orderBy: q => q.OrderBy(d => d.Name));
    ViewBag.SelectedDepartment = new SelectList(departments, "DepartmentID", "Name", SelectedDepartment);

    int departmentID = SelectedDepartment.GetValueOrDefault(); 
    return View(unitOfWork.CourseRepository.Get(
        filter: d => !SelectedDepartment.HasValue || d.DepartmentID == departmentID,
        orderBy: q => q.OrderBy(d => d.CourseID),
        includeProperties: "Department"));
}

Метод получает выбранное значение раскрывающегося списка в параметре SelectedDepartment . Если ничего не выбрано, этот параметр будет иметь значение NULL.

Коллекция SelectList , содержащая все отделы, передается в представление раскрывающегося списка. Параметры, переданные конструктору SelectList , указывают имя поля значения, имя текстового поля и выбранный элемент.

Get Для метода репозитория Course код задает выражение фильтра, порядок сортировки и готовую загрузку для Department свойства навигации. Выражение фильтра всегда возвращается true , если в раскрывающемся списке ничего не выбрано (то есть SelectedDepartment значение NULL).

В Views\Course\Index.cshtml непосредственно перед открывающим table тегом добавьте следующий код, чтобы создать раскрывающийся список и кнопку отправки:

@using (Html.BeginForm())
{
    <p>Select Department: @Html.DropDownList("SelectedDepartment","All")   
    <input type="submit" value="Filter" /></p>
}

Если точки останова по-прежнему заданы в GenericRepository классе, запустите страницу "Индекс курса". Продолжайте через первые два раза, когда код попадает в точку останова, чтобы страница отображалась в браузере. Выберите отдел из раскрывающегося списка и нажмите кнопку "Фильтр":

Снимок экрана: страница

На этот раз первая точка останова будет для отделов запрашивать раскрывающийся список. Пропустите это и просмотрите query переменную при следующем достижении точки останова, чтобы увидеть, как Course выглядит запрос. Вы увидите следующее:

{SELECT 
[Extent1].[CourseID] AS [CourseID], 
[Extent1].[Title] AS [Title], 
[Extent1].[Credits] AS [Credits], 
[Extent1].[DepartmentID] AS [DepartmentID], 
[Extent2].[DepartmentID] AS [DepartmentID1], 
[Extent2].[Name] AS [Name], 
[Extent2].[Budget] AS [Budget], 
[Extent2].[StartDate] AS [StartDate], 
[Extent2].[PersonID] AS [PersonID], 
[Extent2].[Timestamp] AS [Timestamp]
FROM  [Course] AS [Extent1]
INNER JOIN [Department] AS [Extent2] ON [Extent1].[DepartmentID] = [Extent2].[DepartmentID]
WHERE (@p__linq__0 IS NULL) OR ([Extent1].[DepartmentID] = @p__linq__1)}

Вы увидите, что запрос теперь является запросом JOIN , который загружает Department данные вместе с Course данными, и что он включает WHERE предложение.

Работа с классами прокси-сервера

Когда Entity Framework создает экземпляры сущностей (например, при выполнении запроса), он часто создает их в качестве экземпляров динамически созданного производного типа, который выступает в качестве прокси-сервера для сущности. Этот прокси переопределяет некоторые виртуальные свойства сущности, чтобы вставить перехватчики для выполнения действий автоматически при доступе к свойству. Например, этот механизм используется для поддержки отложенной загрузки связей.

В большинстве случаев вам не нужно знать об этом использовании прокси-серверов, но существуют исключения:

  • В некоторых сценариях может потребоваться запретить entity Framework создавать экземпляры прокси-сервера. Например, сериализация экземпляров, не являющихся прокси-серверами, может быть более эффективной, чем сериализация экземпляров прокси-сервера.
  • При создании экземпляра класса сущности с помощью new оператора вы не получаете экземпляр прокси-сервера. Это означает, что вы не получаете такие функции, как отложенная загрузка и автоматическое отслеживание изменений. Обычно это нормально; Обычно не требуется отложенная загрузка, так как вы создаете новую сущность, которая не содержится в базе данных, и обычно не требуется отслеживать изменения, если вы явно помечаете сущность как Added. Однако если вам нужна отложенная загрузка и требуется отслеживание изменений, можно создать новые экземпляры сущностей с прокси-серверами с помощью Create метода DbSet класса.
  • Возможно, потребуется получить фактический тип сущности из типа прокси-сервера. Метод класса можно использовать GetObjectType для получения фактического типа сущности ObjectContext экземпляра прокси-типа.

Дополнительные сведения см. в разделе "Работа с прокси-клиентами " в блоге группы Entity Framework.

Отключение автоматического обнаружения изменений

Платформа Entity Framework определяет, как была изменена сущность (и, соответственно, какие обновления требуется отправить в базу данных), сравнивая текущие значения сущности с исходными. Исходные значения хранятся при запросе или присоединении сущности. Ниже перечислены некоторые из методов, которые приводят к автоматическому обнаружению изменений:

  • DbSet.Find
  • DbSet.Local
  • DbSet.Remove
  • DbSet.Add
  • DbSet.Attach
  • DbContext.SaveChanges
  • DbContext.GetValidationErrors
  • DbContext.Entry
  • DbChangeTracker.Entries

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

Отключение проверки при сохранении изменений

При вызове SaveChanges метода платформа Entity Framework по умолчанию проверяет данные во всех свойствах всех измененных сущностей перед обновлением базы данных. Если вы обновили большое количество сущностей и уже проверили данные, эта работа не требуется, и вы можете сделать процесс сохранения изменений занимает меньше времени, временно отключив проверку. Это можно сделать с помощью свойства ValidateOnSaveEnabled . Дополнительные сведения см. в разделе "Проверка".

Итоги

В этом руководстве описано, как использовать Entity Framework в приложении ASP.NET MVC. Ссылки на другие ресурсы Entity Framework можно найти на карте содержимого доступа к данным ASP.NET.

Дополнительные сведения о развертывании веб-приложения после его создания см. в ASP.NET схеме содержимого развертывания в библиотека MSDN.

Дополнительные сведения о других разделах, связанных с MVC, такими как проверка подлинности и авторизация, см. в рекомендуемых ресурсах MVC.

Благодарности

  • Том Дайкстра написал исходную версию этого учебника и является старшим автором программирования в группе содержимого веб-платформа Майкрософт и инструментов.
  • Рик Андерсон (twitter @RickAndMSFT) совместно написал это руководство и сделал большую часть работы для EF 5 и MVC 4. Rick — старший писатель по программированию для Майкрософт, ориентированный на Azure и MVC.
  • Rowan Miller и другие члены команды Entity Framework помогли с проверками кода и помогли выполнить отладку многих проблем с миграцией, возникающих при обновлении руководства по EF 5.

VB

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

Ошибки и обходные пути

Не удается создать или тень копирования

Сообщение об ошибке:

Не удается создать или теневой копирования DotNetOpenAuth.OpenId, если этот файл уже существует.

Решение.

Подождите несколько секунд и обновите страницу.

Обновление-База данных не распознана

Сообщение об ошибке:

Термин Update-Database не распознается как имя командлета, функции, файла скрипта или операблированных программ. Проверьте орфографию имени или в случае включения пути проверьте правильность указания пути и повторите попытку.(Из Update-Database команды в PMC.)

Решение.

Закройте Visual Studio. Повторно откройте проект и повторите попытку.

Проверка завершена с ошибкой

Сообщение об ошибке:

Сбой проверки для одной или нескольких сущностей. Дополнительные сведения см. в свойстве EntityValidationErrors. (Из Update-Database команды в PMC.)

Решение.

Одна из причин этой проблемы заключается в ошибках проверки при выполнении Seed метода. Сведения об отладке метода см. в разделе "Начальное и отладка DOB-объектов Entity Framework ( EF) для получения советов по отладке Seed метода.

Ошибка HTTP 500.19

Сообщение об ошибке:

Ошибка HTTP 500.19 — внутренняя ошибка сервера
Доступ к запрошенной странице невозможен, так как связанные данные конфигурации для страницы недопустимы.

Решение.

Один из способов получить эту ошибку заключается в наличии нескольких копий решения, каждый из которых использует один и тот же номер порта. Обычно эту проблему можно решить, выходя из всех экземпляров Visual Studio, а затем перезагрузив проект, над которым вы работаете. Если это не работает, попробуйте изменить номер порта. Щелкните правой кнопкой мыши файл проекта и выберите свойства. Выберите веб-вкладку и измените номер порта в текстовом поле "URL-адрес проекта".

Ошибка при обнаружении экземпляра SQL Server

Сообщение об ошибке:

При подключении к SQL Server произошла ошибка, связанная с сетью или с определенным экземпляром. Сервер не найден или недоступен. Проверьте правильность имени экземпляра и настройку сервера SQL Server для удаленных подключений. (поставщик: сетевые интерфейсы SQL, ошибка: 26 — ошибка при обнаружении указанного сервера или экземпляра)

Решение.

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