介绍 K-Pattern:快速进行 Entity Framework CRUD 操作的方法






4.74/5 (20投票s)
本文介绍了我开发的 Entity Framework 模式“K-Pattern”。
引言
去年早些时候,我采用了另一种处理 Entity Framework 的方法,其中我创建了一些类来在单个请求范围内处理 ObjectContext
,并编写了一些扩展方法来处理所有 edmx 设计器类(包括插入/更新/删除)。通过这种方式,我意识到我们可以多么快速地构建应用程序,但其中也存在一些不足之处。我对这些缺点进行了改进,现在它们呈现在您面前。
本文是对我之前文章/技巧 “使用 Entity Framework 的最佳方法” 的重制。我将在本文中介绍 “Helper.cs”
类的新功能和方法,并将其与市场上其他一些方法进行比较。
背景
在阅读本文之前,请先阅读 第一部分,以理解“全局上下文”和“Helper”类。在撰写第一部分后,开发者们就“使用 Entity Framework 的最佳方法”展开了激烈的辩论。为了更好地理解,以下几点使其成为最佳方法:
- DataContext 在
HttpContext
的基础上保持活动状态并进行释放,因此您无需在代码块中反复编写初始化和释放的代码。 - Insert、Delete 和 Update 方法直接附加到 Data Context 实体类,而不会影响原始设计器文件。因此,开发人员无需为每个实体类编写单独的功能来实现这些操作。
- 用于插入和更新的单一方法。
- 易于实施且速度快。
然而,也有其他一些模式遵循相同的规则,但需要编写大量的代码来实现。
有什么新功能?
之前的 “Helper.cs” 不支持对关系实体的插入/更新/删除操作,因此它只能处理单个实体。这是主要的缺点,但现在我添加了一些新方法来克服这个问题。引入了一个新的枚举 Operation
,用于定义 EntitySet 操作,例如 Added
(添加)、Modified
(修改)和 Deleted
(删除)。为 EntityObject、EntityCollection<T> 和 ObjectContext 三个类定义了新的扩展方法。以下列出了这些方法及其类和签名:
类 | 方法 | 描述 |
EntityObject |
AttachMe(this EntityObject objEntity) | 将当前实体对象附加到 Global.cs 中定义的全局上下文中。 |
AttachMe(this EntityObject objEntity, Operation oper) | 将当前实体对象附加到 Global.cs 中定义的全局上下文中,并根据提供的 Operation 枚举更改其状态。 | |
DetachMe(this EntityObject entity) | 从 Global.cs 中定义的全局上下文中分离当前实体对象。 | |
EntityCollection<T> |
AttachUs<T>(this EntityCollection<T> entities, Operation oper) where T : EntityObject | 泛型方法,用于将整个集合附加到 Global.cs 中定义的全局上下文中。 |
DetachUs<T>(this EntityCollection<T> entities) where T : EntityObject | 泛型方法,用于将整个集合附加到 Global.cs 中定义的全局上下文中。 | |
ObjectContext |
AttachObject(this ObjectContext context, EntityObject objEntity) | 将提供的实体附加到提供的上下文。 |
AttachObject(this ObjectContext context, EntityObject objEntity, Operation oper) | 将提供的实体附加到提供的上下文,并根据提供的操作更改其状态。 | |
DetachObject(this ObjectContext Context, EntityObject entity) | 从提供的上下文中分离提供的实体。 |
开始吧
为了演示新方法,我们将创建一个数据库 (db_EntityFrameworkSample)
,并创建两个具有一对多关系的表。
在上面的图表中,有两个表 Course
和 Student
,它们通过一对多关系相关联。我们将按以下顺序对这些表执行操作:
单个实体操作
Course objCourse = new Course { Name = "B.Sc.", Duration = "3 Years" }; objCourse.Save();
插入父项 & 插入子项
Course objCourse = new Course { Name = "M.Sc.", Duration = "3 Years" }; objCourse.AttachMe(); // Here we attached the current object with entity object context to perform operations on children entities objCourse.Students.Add(new Student { Name = "John", FName = "David" }); objCourse.Students.Add(new Student { Name = "Bob", FName = "Jason" }); objCourse.Save();
更新父项 & 插入子项
Course objCourse = Course.GetCourse(2); // Get MCA Cource objCourse.Students.Add(new Student { Name = "Niroo", FName = "Rob" }); objCourse.Students.Add(new Student { Name = "Chirs", FName = "William" }); objCourse.Save();
更新父项 & 更新子项
Course objCourse = Course.GetCourse(2); // Get MCA Course objCourse.Students.ElementAtOrDefault(0).BirthDate = new DateTime(1986, 12, 15); objCourse.Students.ElementAtOrDefault(1).BirthDate = new DateTime(1990, 7, 15); objCourse.Save();
更新父项 & 删除子项
Course objCourse = Course.GetCourse(4); // Get M-Tech Course objCourse.Duration = "4 Years"; objCourse.Students.AttachUs(Operation.Delete); // Attach student with context and change the EntityState to Deleted objCourse.Save();
删除父项 & 删除子项
Course objCourse = Course.GetCourse(3); // Get B-Tech Course objCourse.Students.AttachUs(Operation.Delete); // Attach student with context and change the EntityState to Deleted objCourse.Delete();
以上是使用 “K-Pattern” 定义父子实体之间不同组合的数据操作的示例代码。
与 Repository Pattern 的比较
功能 | K-Pattern | 仓储模式 |
易于实现 | 是 | 否 |
单个请求中的上下文范围 | 是 | 是(使用 IOC) |
适用的项目类型 | 小型和中型项目 | 大型项目 |
对 EF 方法的支持 | 数据库优先 (Database First) | Code First 和 Database First |
结论
以上就是关于 K-Pattern 的全部内容。这个方法还有很多讨论空间,我将期待您的评论和建议,以使其更好。请下载源代码,使用提供的 SQL 脚本创建数据库,更改连接字符串,然后直接运行。
感谢阅读。编码愉快。