仓储模式和MVC帮助

4
我刚开始学习C#和ASP.NET MVC,试图理解仓储模式。我读了很多文章,但是我不知道如何使用它。我目前正在使用LINQ to SQL来访问我SQL Server 2005数据库,并为测试目的创建了两个表。我有一个名为Employees的表和一个名为EmployeeContacts的表。这两个表的主键都是UserName。 Employees
  • UserName
  • LastName
  • FirstName
  • Position
  • Email
  • Status

  • HireDate

EmployeeContacts
  • UserName
  • Contact1
  • Contact1Phone
  • Contact1Relationship
这两个表之间存在一对一的关系。可以添加、更新和删除员工以及EmployeeContacts表中的数据。
那么,我应该创建一个基本仓库供两个实体使用,还是应该为每个实体单独创建一个仓库?如果有人愿意给我展示一些代码,那就太好了。
到目前为止,我有这个员工仓库。我也有一个用于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 继承。我的员工数据保存正确,但员工联系方式却没有保存,我不知道为什么。

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

2个回答

4
我应该创建一个基础仓库,供两个实体使用,还是应该为每个实体分别创建一个仓库?
在使用存储库模式时,一般规则是每个主要实体类型应有一个存储库类。 EmployeeContacts 是否可以独立于任何Employee而存在?如果是这样,它们应该有自己的存储库。它们是否总是与Employee相关联?如果是这样,可以通过使用Employee存储库本身来管理它们。

好的,很有道理。EmployeeContacts 不能没有员工,所以我需要通过 Employee 存储库来管理它们。那么我该怎么做呢?我应该将 EmployeeContacts 的编辑、保存、删除方法添加到 Employee 存储库中吗? - MikeB55

4
使用存储库模式的主要目标(就我所理解的而言)是将应用程序与特定的数据访问层解耦。在这里,您没有做到这一点,因为您创建的EmployeeRepository类没有实现接口。您真正想要的是像EmployeeRepository:IEmployeeRepository这样的东西。
然后,在您的控制器代码中,您可以传递IEmployeeRepository而不是具体使用您的EmployeeRepository。这将给您带来两个好处:
- 如果您需要切换后端代码,则只需创建另一个实现接口的类。 - 当您测试控制器时,可以传递一个实现接口的所谓模拟对象,而不是访问实际数据库,这会减慢测试速度并破坏单元测试。
我注意到的另一件事是,您在存储库中启动了一个DataContext。如果您想更改多种不同类型的对象,则将有多个打开的DataContext,我认为这不是您想要的,因为您的更改不会是事务性的。您可能需要查看工作单元模式以获得解决方案。
学习模式时,请先尝试弄清楚其主要优势,然后再尝试实现它。在某些情况下,可能没有意义。如果您需要我详细说明任何内容,请告诉我。祝你好运。

我找到了一个教程(http://www.asp.net/mvc/tutorials/iteration-4-make-the-application-loosely-coupled-cs),它向我展示了如何实现一个实现接口的仓储模式,就像你提到的那样。我目前正在使用这个测试应用程序,以便我可以理解这个模式。这与Web Forms非常不同,我很难理解它。谢谢你们的帮助,skaz和Konamiman。 - MikeB55
@MikeB55 - 没问题。你要知道,仓储模式也可以用在 Web Forms 上。它是一个通用概念。祝你在 MVC 中好运。 - skaz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接