实体框架 - 断开连接的实体

在本章中,让我们看看如何对未被上下文跟踪的实体进行更改。未被上下文跟踪的实体称为"断开连接的"实体。

  • 对于大多数单层应用程序,用户界面和数据库访问层在同一个应用程序进程中运行,您可能只会对被上下文跟踪的实体执行操作。

  • 断开连接的实体上的操作在 N 层应用程序中更为常见。

  • N 层应用程序涉及从服务器上获取一些数据并通过网络将其返回到客户端计算机。

  • 然后,客户端应用程序会处理这些数据,然后再将其返回到服务器进行持久化。

以下是使用断开连接的实体图甚至单个断开连接的实体需要采取的两个步骤。

  • 将实体附加到新的上下文实例,并使上下文了解这些实体。

  • 手动为这些实体设置适当的 EntityStates。

Change To Entity

让我们看一下以下代码,其中 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 实例,该实例还在其 Enrollments 属性中引用了两个新的 Enrollment 实例。

  • 然后使用 Add 方法将新的 Student 添加到上下文中。

  • 添加 Student 后,代码使用 DbContext.Entry 方法来访问 Entity Framework 拥有的有关新 Student 的更改跟踪信息。

  • 根据此更改跟踪信息,State 属性用于写出实体的当前状态。

  • 然后对从新 Student 引用的每个新创建的 Enrollment 重复此过程。如果运行该应用程序,您将收到以下输出 −

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 方法将标记处于未更改状态的实体。

让我们看一下以下 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...