在软件开发中,数据访问是每个应用程序不可或缺的一部分。为了有效地管理数据访问代码,通常会采用一种称为“仓储模式”的设计模式。这种模式通过在业务逻辑和数据访问层之间添加一个中间层,即仓储层,来隔离数据访问代码。这样做的好处是,当数据库操作需要修改时,只需在一个地方进行更改,而不必在多个控制器方法中重复修改。此外,这种模式还有助于避免代码的重复和提高代码的可维护性。
在不使用仓储模式的情况下,控制器方法会直接与Entity Framework等数据访问技术进行交互。这种方法存在几个问题:
通过使用仓储模式,控制器方法将与仓储层进行交互,而不是直接与数据访问层交互。这种方法的优势包括:
在开始之前,需要准备以下环境:
将创建两个主要的文件夹:
数据访问层包含三个项目,都是类库类型:
在创建项目之前,请确保已经恢复了Northwind数据库。
在Repository_Database项目中,将创建一个数据模型。
// 创建数据模型的步骤
Repository_Database - 右键 -> 添加 -> 新建项 -> 在左侧点击数据 -> 选择ADO.NET实体数据模型 -> 选择从数据库生成() -> 然后选择恢复的Northwind数据库()
// 选择是否在连接字符串中包含路径
// 可以选择为整个数据库创建edmx,或者只为需要的表创建edmx,在本例中将使用客户表
接下来,将为Northwind_DBEntities类创建一个接口:
// 创建接口的步骤
右击 -> 选择重构 -> 提取接口
// 覆盖DbContext的Save方法
在RepositoryPattern_RepoClasses项目中,将添加一个名为CustomerRepository.cs的类,并实现ICustomerRepository接口。
// CustomerRepository类的实现
public class CustomerRepository : ICustomerRepository
{
INorthwind_DBEntities NorthwindContext;
public CustomerRepository(INorthwind_DBEntities db)
{
NorthwindContext = db;
}
public IEnumerable<Customer> SelectAll()
{
return NorthwindContext.Customers.ToList();
}
public Customer SelectByID(string id)
{
return NorthwindContext.Customers.Find(id);
}
public void Insert(Customer obj)
{
NorthwindContext.Customers.Add(obj);
}
public void Delete(string id)
{
var value = NorthwindContext.Customers.Where(i => i.CustomerID == id).FirstOrDefault();
NorthwindContext.Customers.Remove(value);
}
public void Save()
{
NorthwindContext.SaveChanges();
}
}
在RepositoryPattern_RepoInterfaces项目中,将为之前创建的类创建接口。
// ICustomerRepository接口的实现
public interface ICustomerRepository
{
IEnumerable<Customer> SelectAll();
Customer SelectByID(string id);
void Insert(Customer obj);
void Delete(string id);
void Save();
}
在Web文件夹中,将创建一个MVC项目,并添加Autofac和EntityFramework的DLL。
// 创建MVC项目的步骤
右击 -> 选择添加新项目 -> 选择Web -> 选择ASP.NET应用程序 -> 命名项目 ->
// 然后检查MVC并选择空项目
在项目中添加一个控制器,并为其创建视图。然后在控制器中编写以下代码:
// CustomerController类的实现
public class CustomerController : Controller
{
ICustomerRepository _CustomerRepo;
public CustomerController(ICustomerRepository customerRepo)
{
_CustomerRepo = customerRepo;
}
// GET: /Customer/
public ActionResult Index()
{
List<Customer> model = (List<Customer>)_CustomerRepo.SelectAll();
return View(model);
}
public ActionResult Insert(Customer obj)
{
_CustomerRepo.Insert(obj);
_CustomerRepo.Save();
return View();
}
public ActionResult Edit(string id)
{
Customer existing = _CustomerRepo.SelectByID(id);
return View(existing);
}
public ActionResult ConfirmDelete(string id)
{
Customer existing = _CustomerRepo.SelectByID(id);
return View(existing);
}
public ActionResult Delete(string id)
{
_CustomerRepo.Delete(id);
_CustomerRepo.Save();
return View();
}
}
在App_Start文件夹中添加一个名为AutofacConfig.cs的静态类,并在Global.asax中调用这个类的方法。
// AutofacConfig类的实现
public static class AutofacConfig
{
public static void RegisterComponents()
{
var builder = new ContainerBuilder();
builder.RegisterType<CustomerRepository>().As<ICustomerRepository>();
builder.RegisterType<CustomerController>();
builder.RegisterType<Northwind_DBEntities>().As<INorthwind_DBEntities>();
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
}
// Application类的实现
public class Application : System.Web.HttpApplication
{
protected void Application_Start()
{
AutofacConfig.RegisterComponents();
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
}