存储库模式和 MVC 帮助

发布于 2024-12-06 11:52:37 字数 3668 浏览 3 评论 0原文

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

员工 用户

  • 姓氏 名字
  • 电子邮件
  • 职位
  • 状态

  • 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();
    }
}

EmployeeController

我有一个 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;


    }
}
}

代码:

    [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 。我的员工数据保存正确,但员工联系人没有正确保存,我不知道为什么。

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

I'm new to C# and ASP.NET MVC and i'm trying to understand the repository pattern. I've read a whole lot of articles, but I just don't understand how to use it. I'm currently using LINQ to SQL to access my SQL Server 2005 database and for testing purposes I created two tables. I have an Employees table and an EmployeeContacts table. The pk of both tables is UserName.

Employees

  • UserName
  • LastName
  • FirstName
  • Position
  • Email
  • Status

  • HireDate

EmployeeContacts

  • UserName
  • Contact1
  • Contact1Phone
  • Contact1Relationship

There is a one to one relationship between the two tables. An employee can be added, updated, and deleted and so can the data in the EmployeeContacts table.

So would I create a base repository to be used by both entities or should I create a repository for each entity separately? If anybody would be willing to show me some code that would be great.

So far, I have this Employee repository. I also have one for 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();
    }
}

}

I have a class for an 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;


    }
}
}

Code for 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)); 
        }

    }

In my View, i inherit from @model MvcDirectoryLINQ.Models.EmployeeFormViewModel. My Employee data saves correctly but the EmployeeContacts don't and I have no idea why.

Am I implementing the repository pattern correctly?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

安静 2024-12-13 11:52:37

使用存储库模式(据我了解)的主要目标是将应用程序与使用特定数据访问层分离。您尚未在此处执行此操作,因为您创建的我可以看到您的 EmployeeRepository 类未实现接口。您确实想要拥有类似 EmployeeRepository : IEmployeeRepository 的东西

,然后,在您的 Controller 代码中,您可以传递 IEmployeeRepository 而不是具体使用您的 EmployeeRepository >。这将为您带来两个好处:

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

我注意到的另一件事是,您在存储库内部启动了DataContext。如果您想对多种不同类型的对象进行更改,则需要打开多个 DataContext,我认为这不是您想要的,因为您的更改不是事务性的。您可能需要研究工作单元模式来寻找解决方案。

当学习一个模式时,在尝试实现它之前首先尝试找出主要好处。在某些情况下,这可能没有意义。如果您希望我详细说明任何内容,请告诉我。祝你好运。

The main goal when using the Repository Pattern (as far as I understand it) is to decouple your application from using a specific Data Access Layer. You haven't done that here because you create I can see that your EmployeeRepository class does not implement an interface. You really want to have something like EmployeeRepository : IEmployeeRepository

Then, in your Controller code, you can pass around an IEmployeeRepository instead of working concretely with your EmployeeRepository. This will give you two benefits:

  • Should you ever need to switch the backend code, you only need to make another class that implements the interface.
  • When you go to test your Controllers, you can pass around a so called mock object that implements the interface instead of hitting the actual database, which slows your tests down and also breaks Unit Testing.

Another thing I noticed is that you spin up a DataContext inside your repository. If you wanted to make changes to multiple different types of objects you would therefore have multiple DataContexts open, which I don't think is what you want, since your changes won't be transactional. You may want to look into the Unit of Work Pattern for a solution.

When learning about a pattern, try to figure out the main benefit first before trying to implement it. In some cases it may not make sense. Please let me know if you would like me to elaborate on anything. Good luck.

栩栩如生 2024-12-13 11:52:37

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

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

So would I create a base repository to be used by both entities or should I create a repository for each entity separately?

The general rule when using the repository pattern is that there should be one repository class per each primary entity type. Can the EmployeeContacts live independently of any Employee? If so, they should have their own repository. Are them always related to an Employee? If so, manage them by using the Employee repository itself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文