实体框架现在允许您从实体框架中受益,而不必强迫您的应用程序的每个部分都知道实体框架,将实体与基础结构分离.您可以创建可以专注于业务规则的类,而不必考虑它们的持久性(数据的存储位置以及数据在对象之间来回传递的方式).
创建持久性无知实体
前一段描述了一种方法,该方法对其消耗的数据来源并不了解.这突出了持久性无知的本质,即当你的类及其周围的许多应用程序层不关心数据的存储方式时.
在.NET 3.5版本的Entity Framework中,如果要使用预先存在的类,则需要通过强制它们从EntityObject派生来修改它们.
在.NET 4中不再需要这样做.您不必修改实体,以便它们参与实体框架操作.
这使我们能够构建包含松散耦合和分离的应用程序关注.
使用这些编码模式,您的类只关注自己的工作,并且您的应用程序的许多层(包括UI)都没有依赖关系在外部逻辑上,例如实体框架API,但那些外部API能够与我们的实体进行交互.
有两种方式使用实体框架持久化实体时(已连接和已断开连接).两种方式都有其重要性.在连接方案的情况下,更改由上下文跟踪,但在断开连接的方案的情况下,我们需要通知上下文有关实体的状态.
已连接的方案
连接方案是从数据库中检索实体并在同一上下文中修改的实体.对于连接方案,让我们假设我们有一个Windows服务,我们正在与该实体进行一些业务操作,因此我们将打开上下文,遍历所有实体,执行业务操作,然后使用我们相同的上下文保存更改在开头打开.
让我们看一下以下示例,其中从数据库中检索学生并更新学生的名字,然后将更改保存到数据库.
class Program { static void Main(string[] args) { using (var context = new MyContext()) { var studentList = context.Students.ToList(); foreach (var stdnt in studentList) { stdnt.FirstMidName = "Edited " + stdnt.FirstMidName; } context.SaveChanges(); //// Display all Students from the database var students = (from s in context.Students orderby s.FirstMidName select s).ToList(); Console.WriteLine("Retrieve all Students from the database:"); foreach (var stdnt in students) { string name = stdnt.FirstMidName + " " + stdnt.LastName; Console.WriteLine("ID: {0}, Name: {1}", stdnt.ID, name); } Console.ReadKey(); } }}
编译并执行上述代码后,您将收到以下输出,您将看到已编辑的单词附加在第一个名称之前,如下面的输出所示.
Retrieve all Students from the database: ID: 1, Name: Edited Edited Alain Bomer ID: 2, Name: Edited Edited Mark Upston
断开连接的场景
断开连接的场景是指从数据库中检索实体并在不同的上下文中进行修改.假设我们想要在表示层中显示一些数据,并且我们正在使用一些n层应用程序,因此最好打开上下文,获取数据并最终关闭上下文.由于这里我们已经获取数据并关闭了上下文,因此不再跟踪我们获取的实体,这是断开连接的场景.
让我们来看看下面的代码使用Add方法将新的断开连接的Student实体添加到上下文中.
class Program { static void Main(string[] args) { var student = new Student { ID = 1001, FirstMidName = "Wasim", LastName = "Akram", EnrollmentDate = DateTime.Parse( DateTime.Today.ToString()) }; using (var context = new MyContext()) { context.Students.Add(student); context.SaveChanges(); //// Display all Students from the database var students = (from s in context.Students orderby s.FirstMidName select s).ToList(); Console.WriteLine("Retrieve all Students from the database:"); foreach (var stdnt in students) { string name = stdnt.FirstMidName + " " + stdnt.LastName; Console.WriteLine("ID: {0}, Name: {1}", stdnt.ID, name); } Console.ReadKey(); } }}
编译并执行上述代码时,您将收到以下输出.
Retrieve all Students from the database:ID: 1, Name: Edited Edited Edited Alain BomerID: 2, Name: Edited Edited Edited Mark UpstonID: 3, Name: Wasim Akram