Entity Framework - отключенные сущности

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

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

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

  • N-уровневые приложения предполагают получение некоторых данных с сервера и их возврат по сети на клиентский компьютер.

  • Затем клиентское приложение обрабатывает эти данные перед тем, как вернуть их на сервер для сохранения.

Ниже приведены два шага, которые необходимо предпринять с графом отключенных объектов или даже с одним отключенным объектом.

  • Присоедините сущности к новому экземпляру контекста и сделайте контекст осведомленным об этих сущностях.

  • Установите соответствующие EntityStates для этих сущностей вручную.

Давайте посмотрим на следующий код, в котором сущность Student добавлена ​​с двумя сущностями Enrollment.

class Program {

   static void Main(string[] args) {

      var student = new Student {

         ID = 1001,
         FirstMidName = "Wasim",
         LastName = "Akram", 

         EnrollmentDate = DateTime.Parse("2015-10-10"), 
            Enrollments = new List<Enrollment> {

               new Enrollment{EnrollmentID = 2001,CourseID = 4022, StudentID = 1001 },
               new Enrollment{EnrollmentID = 2002,CourseID = 4025, StudentID = 1001 },
         }
      };

      using (var context = new UniContextEntities()) {

         context.Students.Add(student);
         Console.WriteLine("New Student ({0} {1}): {2}", 
            student.FirstMidName, student.LastName, context.Entry(student).State);

         foreach (var enrollment in student.Enrollments) {
            Console.WriteLine("Enrollment ID: {0} State: {1}", 
               enrollment.EnrollmentID, context.Entry(enrollment).State);
         }

         Console.WriteLine("Press any key to exit...");
         Console.ReadKey();
      }
   } 
}
  • Код создает новый экземпляр Student, который также ссылается на два новых экземпляра Enrollment в своем свойстве Enrollments.

  • Затем новый Студент добавляется в контекст с помощью метода Добавить.

  • После добавления Student код использует метод DbContext.Entry для получения доступа к информации отслеживания изменений, которую Entity Framework имеет о новом Student.

  • На основе этой информации отслеживания изменений свойство State используется для записи текущего состояния объекта.

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

New Student   (Wasim  Akram): Added
Enrollment ID: 2001 State: Added
Enrollment ID: 2002 State: Added
Press any key to exit...

В то время как DbSet.Add используется для сообщения Entity Framework о новых сущностях, DbSet.Attach используется для сообщения Entity Framework о существующих сущностях. Метод Attach пометит объект в состоянии Unchanged.

Давайте посмотрим на следующий код C #, в котором отключенная сущность присоединяется с помощью DbContext.

class Program {

   static void Main(string[] args) {

      var student = new Student {

         ID = 1001,
         FirstMidName = "Wasim",
         LastName = "Akram",
         EnrollmentDate = DateTime.Parse("2015-10-10"), 

         Enrollments = new List<Enrollment> {
            new Enrollment { EnrollmentID = 2001, CourseID = 4022, StudentID = 1001 },
            new Enrollment { EnrollmentID = 2002, CourseID = 4025, StudentID = 1001 },
         }
			
      };

      using (var context = new UniContextEntities()) {

         context.Students.Attach(student);
         Console.WriteLine("New Student ({0} {1}): {2}", 
            student.FirstMidName, student.LastName, context.Entry(student).State);

         foreach (var enrollment in student.Enrollments) {
            Console.WriteLine("Enrollment ID: {0} State: {1}", enrollment.EnrollmentID, 
               context.Entry(enrollment).State);
         }

         Console.WriteLine("Press any key to exit...");
         Console.ReadKey();
      }
   }
}

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

New Student   (Wasim  Akram): Unchanged
Enrollment ID: 2001 State: Unchanged
Enrollment ID: 2002 State: Unchanged
Press any key to exit...