Расширенные сценарии 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 First включает методы, позволяющие передавать команды 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для . При выполнении HttpGetUpdateCourseCredits метода переменная будет иметь значение NULL, multiplier а в представлении будет отображаться пустое текстовое поле и кнопка отправки, как показано на предыдущем рисунке.

При нажатии кнопки Обновить и выполнении HttpPostmultiplier метода в текстовом поле будет введено значение . Затем код вызывает метод репозитория 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-запросах см. в статье Необработанные SQL-запросы в блоге команды Entity Framework.

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

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

С помощью метода можно указать, отслеживает ли контекст объекты сущности 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 блок метода , HttpPostEdit чтобы вызвать этот новый метод, если ошибки проверки отсутствуют. Блок 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(); операторов Get и return orderBy(query).ToList(); метода . Запустите проект в режиме отладки и выберите страницу Индекс курса. Когда код достигает точки останова, изучите переменную 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.

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

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

VB

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

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

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

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

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

Решение.

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

Update-Database не распознано

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

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

Решение.

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

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

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

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

Решение.

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

Ошибка HTTP 500.19

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

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

Решение.

Один из способов получить эту ошибку — наличие нескольких копий решения, каждая из которых использует один и тот же номер порта. Обычно эту проблему можно решить, выйдя из всех экземпляров Visual Studio, а затем перезапустив проект, над которым вы работаете. Если это не сработает, попробуйте изменить номер порта. Щелкните правой кнопкой мыши файл проекта и выберите свойства. Перейдите на вкладку Интернет и измените номер порта в текстовом поле Url-адрес проекта .

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

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

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

Решение:

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