存储库模式和MVC帮助

时间:2011-09-27 13:40:35

标签: c# linq-to-sql asp.net-mvc-2 repository

我是C#和ASP.NET MVC的新手,我正在尝试理解存储库模式。我已经阅读了很多文章,但我只是不明白如何使用它。我目前正在使用LINQ to SQL访问我的SQL Server 2005数据库,出于测试目的,我创建了两个表。我有一个Employees表和一个EmployeeContacts表。两个表的pk都是UserName。

员工

  • 用户名
  • 名字
  • 位置
  • 电子邮件
  • 状态

  • 雇佣日期

EmployeeContacts

  • 用户名
  • Contact1
  • Contact1Phone
  • Contact1Relationship

两个表之间存在一对一的关系。可以添加,更新和删除员工,EmployeeContacts表中的数据也可以添加,更新和删除。

那么我会创建一个供两个实体使用的基本存储库,还是应该为每个实体单独创建一个存储库?如果有人愿意向我展示一些很棒的代码。

到目前为止,我有这个Employee存储库。我还有一个EmployeeContacts

namespace MvcDirectoryLINQ.Models
{
public class EmployeeRepository
{
    private TestDB_DataDataContext db = new TestDB_DataDataContext();
    private UserName u = new UserName(); 

    //
    // Query Methods

    public IQueryable<Employee> FindAllEmployees()
    {
        return db.Employees;
    }

    public IQueryable<Employee> FindRecentEmployees()
    {
        DateTime myDate = DateTime.Today.AddMonths(-6); 

        return from empl in db.Employees
               where empl.HireDate >= myDate
               orderby empl.HireDate 
               select empl;
    }

    public Employee GetEmployee(string UserName)
    {

        return db.Employees.SingleOrDefault(d => d.UserName == UserName);
    }

    //
    // Insert/Delete Methods

    public void Add(Employee employee)
    {

       // get the UserName which is created from the email
        employee.UserName = u.ReturnUserName(employee.Email); 

        //Insert the new employee into the database
        db.Employees.InsertOnSubmit(employee);
        db.EmployeeContacts.InsertOnSubmit(employee.EmployeeContact); 
    }

    public void Delete(Employee employee)
    {
        db.EmployeeContacts.DeleteOnSubmit(employee.EmployeeContact);
        db.Employees.DeleteOnSubmit(employee);
    }

    //
    // Persistence

    public void Save()
    {
        db.SubmitChanges();
    }
}

}

我有一个EmployeeFormViewModel的课程:

namespace MvcDirectoryLINQ.Models
{
public class EmployeeFormViewModel
{
    //Properties
    public Employee Employee { get; private set; }
    public EmployeeContact EmployeeContact { get; private set; }


    //Constructor
    public EmployeeFormViewModel(Employee employee, EmployeeContact employeeContact)
    {

        Employee = employee;
        EmployeeContact = employeeContact;


    }
}
}

EmployeeController的代码:

    [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(string UserName, FormCollection formValues)
    {

        Employee employee = employeeRepository.GetEmployee(UserName);

        EmployeeContact employeecontact = employeecontactRepository.GetContact(UserName); 

        try
        {


            UpdateModel(employee);
            UpdateModel(employeecontact);


            employeecontactRepository.Save(); 
            employeeRepository.Save();


            return RedirectToAction("Details", new { UserName = employee.UserName });
        }
        catch
        {

            foreach (var issue in employee.GetRuleViolations())
            {
                ModelState.AddModelError(issue.PropertyName, issue.ErrorMessage);
            }


            return View(new EmployeeFormViewModel(employee, attendingID)); 
        }

    }

在我的视图中,我继承自@model MvcDirectoryLINQ.Models.EmployeeFormViewModel。我的员工数据保存正确,但EmployeeContacts没有,我不明白为什么。

我是否正确实施了存储库模式?

2 个答案:

答案 0 :(得分:4)

那么我会创建一个供两个实体使用的基础存储库,还是应该为每个实体单独创建一个存储库?

使用存储库模式时的一般规则是每个主要实体类型应该有一个存储库类。 EmployeeContacts可以独立于任何Employee生活吗?如果是这样,他们应该拥有自己的存储库。他们总是与员工有关吗?如果是这样,请使用Employee存储库本身管理它们。

答案 1 :(得分:4)

使用存储库模式(据我所知)的主要目标是将应用程序与使用特定数据访问层分离。你没有在这里做过,因为你创建我可以看到你的EmployeeRepository类没有实现一个接口。你真的想拥有像EmployeeRepository : IEmployeeRepository

这样的东西

然后,在您的控制器代码中,您可以传递IEmployeeRepository而不是与EmployeeRepository具体合作。这将为您带来两个好处:

  • 如果您需要切换后端代码,您只需要创建另一个实现该接口的类。
  • 当你去测试你的控制器时,你可以传递一个所谓的模拟对象来实现接口,而不是点击实际的数据库,这会减慢你的测试速度并打破单元测试。

我注意到的另一件事是你在你的存储库中启动了DataContext 。如果您想对多个不同类型的对象进行更改,那么您将打开多个DataContext,我认为这不是您想要的,因为您的更改不会是事务性的。您可能需要查看Unit of Work模式以获得解决方案。

在了解模式时,在尝试实现模式之前,先尝试找出主要优势。在某些情况下,它可能没有意义。如果您希望我详细说明,请告诉我。祝你好运。