如何在ASP.NET MVC中组织DAL

时间:2015-02-05 07:58:32

标签: c# asp.net-mvc data-access-layer

我正在尝试在asp.net mvc项目中组织数据访问层。我已经阅读了很多不同的文章,所以我仍然有一些问题要完成这个问题:

  1. 我应该为数据库中的每个实体创建存储库实例,还是为所有或一个基本实例创建存储库实例,例如PostRepository可以包含PostComment和{{}等实体1}}

  2. 在控制器中,我必须获取一些数据,转换为ViewModel并将其传递给视图。这是最好的去处? TagServices或其他什么?

  3. 如果是Controller。我应该创建多少服务?对于每个实体,如果是必要的话,还会转入Controller 3或4服务?或者也许就像我想在存储库中这样做? (创建一个包含一些存储库数量的公共服务。Service,包含PostServicePostRepositoryCommentRepository等存储库

2 个答案:

答案 0 :(得分:3)

这是我的看法:

  

我应该为数据库中的每个实体创建存储库实例   或者对于所有或一个基本实例,例如PostRepository都可以   包括Post,Comment和Tag等实体?

拥有一个通用存储库可以为您节省大量的维护工作。您可以实现单个通用存储库,如:

/// <summary>
/// This interface provides an abstraction for accessing a data source.
/// </summary>
public interface IDataContext : IDisposable
{
    IQueryable<T> Query<T>() where T : class;

    T Add<T>(T item) where T : class;

    int Update<T>(T item) where T : class;

    void Delete<T>(T item) where T : class;

    /// <summary>
    /// Allow repositories to control when SaveChanges() is called
    /// </summary>
    int SaveChanges();
}

并在单个上下文类中实现上面的接口。

有些人也会实施单独的特定存储库。

  

在控制器中我必须得到一些数据,转换成ViewModel和   把它传递给视野。这是最好的去处?服务,   控制器或其他什么?

在可从DA,服务和Web访问的单独程序集中定义所有模型(DTO或实体或POCO)类。服务方法返回模型实例,控制器将它们转换为viewmodel(使用AutoMapper)并传递给视图。同样在post方法控制器中,首先将VM转换为Model,然后传递给Service层以进行持久性或处理。

  

如果是服务。我应该创建多少服务?也适合每一个人   实体并在必要时转入Controller 3或4服务?要么   也许就像我想在存储库中做到这一点? (创造一个共同的   服务,其中包含一些存储库计数。 PostService,   使用PostRepository,CommentRepository等存储库   TagRepository)

我强烈建议您定义非常具体的服务。使用单一责任原则来定义您的服务。每项服务都应提供相关的功能集。例如。 AuthService将验证用户不向他们发送电子邮件,即EmailService作业。

我建议的模式与不同的服务非常合作。例如:

public class DriverSearchService : IDriverSearchService
{
    private readonly IBlobService _blobService;
    private readonly IDataContext _dataContext;

    public DriverSearchService(IDataContext dataContext, IBlobService blobService)
     {
         _blobService = blobService;
        _dataContext = dataContext;
     }

    public void SaveDriveSearch(int searchId)
    {
        // Fetch values from temp store and clear temp store
        var item = context.Query<SearchTempStore>().Single(s => s.SearchId == searchId);

        // Temp object is latest so update the main store
        var mainSearch = context.Query<Search>().Single(s => s.Id == searchId);
        mainSearch.LastExecutedOn = DateTime.UtcNow;
        mainSearch.DataAsBlob = item.DataAsBlob;
        context.Update(mainSearch);
    }
}

答案 1 :(得分:1)

基本上我同意@ChrFin评论你的帖子,但无论如何我想回答你的问题。

  1. 是的,但仅在您需要的时候。您应该考虑Post实体可能具有引用其他实体的虚拟属性。如果是这样,您可能不需要分隔存储库。但是,在加载相关实体时,您应该考虑性能问题

  2. 根据我的经验,映射到ViewModel的最佳位置是服务层或管理层 - 取决于您想要如何调用它。我总是尽量让控制器变薄。随着应用程序的增长,您可能希望在其他应用程序中重用逻辑,例如: WCF。如果您有转换,业务逻辑,控制器中的其他内容,您将无法共享

  3. 取决于。如果你想避免控制器中的多个依赖项(这也会影响单元测试),你应该为每个控制器创建一个服务 - 正如我所说的那样,这不是规则。服务可能包含多个存储库。通常,您不希望使用与存储库一样多的服务。

  4. 如果您正在开始开发应用程序,则应在决定使用存储库模式之前检查此有用链接:

    Favor query objects over repositories

    Say No to the Repository Pattern in your DAL