如何在 ASP.NET MVC 中组织 DAL [关闭]
Posted
技术标签:
【中文标题】如何在 ASP.NET MVC 中组织 DAL [关闭]【英文标题】:How to organize DAL in ASP.NET MVC [closed] 【发布时间】:2015-04-05 00:10:35 【问题描述】:我正在尝试在 asp.net mvc 项目中组织数据访问层。我已经阅读了很多关于此的不同文章,所以我仍然有一些问题要解决这个问题:
我应该为数据库中的每个实体还是为所有或一个通用实例创建存储库实例,例如 PostRepository
可以包括 Post
、Comment
和 Tag
等实体?
在控制器中,我必须获取一些数据,转换为 ViewModel 并将其传递到视图中。最好的地方在哪里? Services
、Controller
还是别的什么?
如果是Service
。我应该创建多少服务?是否也适用于每个实体并在必要时传递给控制器 3 或 4 服务?或者也许像我想在存储库中那样做? (创建一个包含一些存储库的公共服务。PostService
,具有诸如PostRepository
、CommentRepository
和TagRepository
之类的存储库)
【问题讨论】:
这主要是基于意见的,因为没有一般的“对与错”。它还取决于您的特定用例和偏好。在这种情况下,我自己根本不喜欢存储库,因为DbContext
是我的存储库 IMO...
【参考方案1】:
这是我的看法:
我应该为数据库中的每个实体创建存储库实例吗 或者对于所有或一个通用实例,例如 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)类。服务方法返回模型实例,控制器将它们转换为视图模型(使用 AutoMapper)并传递给视图。再次在 post 方法中,控制器首先将 VM 转换为 Model,然后传递给 Service 层进行持久化或处理。
如果是服务。我应该创建多少服务?也为每个 实体并在必要时传递给控制器 3 或 4 服务?要么 也许像我想在存储库中那样做? (创建一个公共 服务将包含一些存储库。邮政服务, 使用 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);
【讨论】:
【参考方案2】:基本上我同意@ChrFin 对你帖子的评论,但我还是想回答你的问题。
可以,但前提是您需要。您应该考虑Post
实体可能具有引用其他实体的虚拟属性。在这种情况下,您可能不需要单独的存储库。但是,您应该在加载相关实体时考虑性能问题。
根据我的经验,映射到 ViewModel 的最佳位置是服务层或管理器层 - 取决于您要如何调用它。我总是尽量保持我的控制器薄。随着应用程序的增长,您可能希望在其他应用程序中重用您的逻辑,例如WCF。如果您的控制器中有转换、业务逻辑和其他内容,您将无法共享它们。
视情况而定。如果您想避免控制器中的多个依赖项(这也对单元测试产生影响),您应该为每个控制器创建一个服务 - 正如我所说的那样,这不是规则。服务可能包含多个存储库。通常,您不希望服务与存储库一样多。
如果您开始开发应用程序,您应该在决定使用存储库模式之前查看这些有用的链接:
Favor query objects over repositories
Say No to the Repository Pattern in your DAL
【讨论】:
以上是关于如何在 ASP.NET MVC 中组织 DAL [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
如何将数据从表示层传递到业务逻辑层? (ASP.NET MVC 5)