使用实体框架学习MVC3应用中的MVC - Part 5存储库模式

介绍 在前四篇文章中,我们学习了几乎所有关于如何创建MVC应用程序以及如何使用相同的应用程序与数据库通信的知识。 在学习MVC的第三部分,我们使用EntityFramework学习了MVC应用程序和数据库之间的沟通,所以我是在引用相同的上下文。在本文中,我将重点讨论如何在相同的MVC应用程序中实现存储库模式,从而向开发企业应用程序的体系结构方法迈进一步。 我们的路线图 只是为了提醒你我们学习MVC的完整路线图: 第一部分:介绍MVC架构和关注点分离第2部分:从头创建MVC应用程序并使用LINQ to SQL将其与数据库连接第3部分:使用EntityFramework DB-First方法连接MVC应用程序。第4部分:使用EntityFramework代码优先方法连接MVC应用程序第5部分:使用EntityFramework. 在MVC应用程序中实现存储库模式第6部分:使用EntityFramework. 在MVC应用程序中实现通用存储库模式和工作单元模式 的必备条件 在开始文章之前,有几个先决条件: 在本系列文章的第3部分中,我们创建了运行的示例应用程序。我们有EntityFramework 4.1包或DLL在我们的本地文件系统。我们了解MVC应用程序是如何创建的。 库模式 很少有作者解释模式的概念并直接跳过模式的实际实现。那么,首先让我们了解什么是存储库模式?我们为什么要使用它? 简单地说,存储库基本上充当我们的业务逻辑层和应用程序的数据访问层之间的中介。有时,将数据访问机制直接公开给业务逻辑层会很麻烦,可能会导致访问类似实体的数据的冗余代码,或者导致代码难以测试或理解。为了克服这类问题,并编写接口驱动和测试驱动代码来访问数据,我们使用了存储库模式。存储库向数据源查询数据,然后将数据从数据源映射到业务实体/域对象,最后将业务实体中的更改持久化到数据源。根据MSDN,存储库将业务逻辑从与底层数据源或Web服务的交互中分离出来。数据层和业务层之间的分离有三个好处: 它集中了数据逻辑或Web服务访问逻辑。它为单元测试提供了替换点。它提供了一种灵活的体系结构,可以随着应用程序总体设计的发展而进行调整。 当我们使用实体框架时,就像我们在上一个创建的应用程序中所做的那样,我们在控制器类中调用实体框架类对象来访问实体类。现在我们可以说这个系统是一个紧密耦合的系统。如前所述,为了克服这种情况,我们将实现存储库模式。 在Repository中,我们在实体框架类的帮助下编写了CRUD操作的整个业务逻辑,这不仅会产生有意义的测试驱动代码,还会减少访问数据的控制器代码。 创建存储库 创建存储库并不像听起来那么困难,一旦你自己实现了它,你会爱上它的。 步骤1:在Visual Studio中打开我们现有的MVC3应用程序,它是我们在第三部分中创建的,在Entity Framework的帮助下与数据库交互。 步骤2:创建名为Repository的文件夹并向名为IUserRepository的文件夹添加接口,该接口来自IDisposable类型的接口。 我们将在这里对User entity类声明用于CRUD操作的方法,您可以根据自己的选择选择方法的名称,但这些应该很容易理解和遵循。 就像我在下面使用的代码,我的界面: 隐藏,复制Code

using System;
using System.Collections.Generic;

namespace LearningMVC.Repository
{
    public interface IUserRepository:IDisposable
    {
        IEnumerable<User> GetUsers();
        User GetUserByID(int userId);
        void InsertUser(User user);
        void DeleteUser(int userId);
        void UpdateUser(User user);
        void Save();
    }
}

我们可以看到,每个方法名都表示用户实体上的特定CRUD操作。 User实体与我们在模型中生成的实体相同。学习MVC第三部分的tt课程,还记得吗? 步骤3:从该接口提取一个类,并将其称为UserRepository。这个UserRepository类将实现该接口的所有方法,但是在实体框架的帮助下。现在来使用我们的DBContext类MVCEntities,我们已经有这个类在我们现有的解决方案,所以我们不需要触摸这个类,简单地,写我们的业务逻辑在接口方法实现在UserRepository类: 隐藏,收缩,复制Code

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;

namespace LearningMVC.Repository
{
    public class UserRepository:IUserRepository
    {
        private MVCEntities context;

        public UserRepository(MVCEntities context)
        {
            this.context = context;
        }

        public IEnumerable<User> GetUsers()
        {
            return context.Users.ToList();
        }

        public User GetUserByID(int userId)
        {
            return context.Users.Find(userId);
        }

        public void InsertUser(User user)
        {
            context.Users.Add(user);
        }

        public void DeleteUser(int userId)
        {
            User user = context.Users.Find(userId);
            context.Users.Remove(user);
        }

        public void UpdateUser(User user)
        {
            context.Entry(user).State = EntityState.Modified;
        }

        public void Save()
        {
            context.SaveChanges();
        }

        private bool disposed = false;

        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    context.Dispose();
                }
            }
            this.disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    }
}

在解决方案里面: 接口 类 现在90%的工作已经完成了。现在只剩下在控制器中使用这个存储库。 无需解释如何调用re在控制器内部,你现在知道了如何处理控制器,但还是让我们做一次。 步骤4:转到控制器,声明IUserRepository引用,并在构造函数中使用UserRepository类初始化对象,将MVCEntities作为参数传递给构造函数,我们在UserRepository类中定义: 隐藏,复制Code

#region Private member variables...
private IUserRepository userRepository; 
#endregion

#region Public Constructor...
/// <summary>
/// Public Controller to initialize User Repository
/// </summary>
public MyController()
{
this.userRepository = new UserRepository(new MVCEntities());
} 
#endregion

在这个解决方案中,它看起来像: 步骤5:现在对于直接使用实体框架上下文的控制器的所有操作,我们用创建的userRepository对象替换调用逻辑,并调用repository类中定义的方法。 比如在索引控制器中,我们显示用户列表,我们做: 隐藏,复制Code

var userList = from user in userRepository.GetUsers() select user;
            var users = new List<LearningMVC.Models.UserList>();
            if (userList.Any())
            {
                foreach (var user in userList)
                {
                    users.Add(new LearningMVC.Models.UserList() 
                    { UserId = user.UserId, Address = user.Address, 
                    Company = user.Company, FirstName = user.FirstName, 
                    LastName = user.LastName, Designation = user.Designation, 
                    EMail = user.EMail, PhoneNo = user.PhoneNo });
                }
            }

我们可以看到之前使用的代码保持不变,在实体框架数据访问层和业务逻辑之间只引入了一层,控制器现在只使用该抽象层与数据库通信。 控制器的其他动作也类似: 细节 创建 编辑 删除 第6步:运行应用程序,我们会看到应用程序像之前一样运行: 现在是派对时间了。 结论 我们现在也知道了如何创建存储库,以及如何使用它执行CRUD操作。 现在,我们可以看到该模式有多有用,以及它如何解决紧耦合问题并产生合适的体系结构。 根据MSDN,使用存储库模式来实现以下一个或多个目标: 您希望最大化可以通过自动化测试的代码数量,并隔离数据层以支持单元测试。您从许多位置访问数据源,并希望应用集中管理的、一致的访问规则和逻辑。您希望为数据源实现和集中缓存策略。您希望通过将业务逻辑与数据或服务访问逻辑分离来提高代码的可维护性和可读性。您希望使用强类型的业务实体,以便可以在编译时而不是在运行时识别问题。您希望将行为与相关数据关联起来。例如,您希望计算字段或在实体内的数据元素之间执行复杂关系或业务规则。您希望应用域模型来简化复杂的业务逻辑。 我完全同意,但是我们的应用程序是否恰当地使用了这种模式?如果需要创建100多个存储库怎么办?如果我们有100多个实体呢?我们是否为它们都创建了存储库,从而导致混乱和代码冗余?答案是否定的。在本系列的下一篇也是最后一篇文章中,我们将学习如何创建一个通用存储库来满足n个实体的需求。本文和现有文章的源代码,即。,第3部分以及数据库脚本已经附上。你可以下载并运行这个解决方案,如果你想问的话,可以给我一个问题。我很乐意回答。 编码:快乐), 本文转载于:http://www.diyabc.com/frontweb/news415.html

posted @ 2020-08-06 17:39  Dincat  阅读(125)  评论(0编辑  收藏  举报