如何在n层体系结构中将entity framework模型类与Business Layer类映射 – ASP.NET-MVC

我正在研究MVC框架(ASP.NET MVC5,Entity Framework 6)中的e层架构。 我的应用程序分为三个子项目,分别是业务层,数据访问层,存储库(包括存储库和工作单元)和ASP.NET MVC web-app。 我正在努力理解业务数据和entity framework模型之间的映射。 例如,如果我在entity framework中有模型类User

DAL – 用户模型

[Table("User")] public class User { public User() { } [Key] public int UserID { get; set; } [StringLength(250)] [Required] public string FirstName { get; set; } [StringLength(250)] [Required] public string LastName { get; set; } [Required] public int Age { get; set; } [StringLength(250)] [Required] public string EmailAddress { get; set; } public ICollection UserInGroup { get; set; } } 

在业务层我有用户类

BLL – 用户类

 public class User { private string userID; private string firstName; private string lastName; private int age; private string emailAddress; public string UserID { get { return userID; } set { userID = value; } } public string FirstName { get { return firstName; } set { firstName = value; } } public string LastName { get { return lastName; } set { lastName = value; } } public int Age { get { return age; } set { age = value; } } public string EmailAddress { get { return emailAddress; } set { emailAddress = value; } } public void GetAllUser() { List _user = new List(); using (var _uow = new UserManagement_UnitOfWork()) { _user = (from u in _uow.User_Repository.GetAll() select u).ToList(); } } } 

我如何映射,其次; 参考方法GetAllUser(),我仍然需要使用DAL中的User模型类来从数据库中获取所有用户,我目前的理解是在哪里; 每一层应该彼此独立,我有抽象层,即数据访问层和业务层之间的存储库。 我对这两个概念一起工作有点困惑。 我是在正确的轨道还是错过了什么。 用户业务层也需要实际答案。

您只需使用AutoMapper通过Nuget安装它即可:

 PM> Install-Package AutoMapper 

然后你要做的就是配置AutoMapper来为你映射类似的对象。

 Mapper.CreateMap(); 

你可以在任何地方转换对象:

 BLL.User bll_User = Mapper.Map(dal_user); 

您的问题更多的是关于没有“一刀切”解决方案的设计/架构。 我最多可以分享一些建议,我通常会在一个相当典型的ASP.NET MVC + Entity Framework堆栈中做些什么:

1.确保您的BLL.User类遵守单一责任原则

您的BLL.User类不应该关注如何通过Entity Framework / Unit of Work从数据库中检索DAL.User 。 你应该只是有另一个类/层负责:

 public interface IUserRepository { IEnumerable GetAllUsers(); } 

然后另一个类来实现IUserRepository

 public class UserRepository : IUserRepository { private readonly UserManagement_UnitOfWork _unitOfWork; public UserRepository(UserManagement_UnitOfWork unitOfWork) { _unitOfWork = unitOfWork; } public IEnumerable GetAllUsers() { return from u in _unitOfWork.User_Repository.GetAll() select u; } } 

这样做会消除BLL.UserUserManagment_UnitOfWork类的依赖性,并促进测试/模拟(即可以编写unit testing来模拟内存中的IUserRepository

然后从您的控制器,只要需要检索BLL.Users ,您只需将IUserRepository的实例注入控制器的构造函数:

 public class UserController { private readonly IUserRepository _userRepository; public UserController(IUserRepository userRepository) { _userRepository = userRepository; } public ActionResult Index() { // Simple example using IEnumerable as the view model return View(_userRepository.GetAllUsers().ToList()); } } 

2.如何将DAL.User映射到BLL.User

它实际上非常类似于第1点,你可以简单地拥有另一个接口/类对:

 public interface IUserMapper { BLL.User MapUser(DAL.User); } public class UserMapper : IUserMapper { public BLL.User MapUser(DAL.User user) { return new BLL.User { FirstName = user.FirstName, LastName = user.LastName, Age = user.Age // etc... }; } } 

或者,如果您认为编写映射代码很繁琐,请考虑使用AutoMapper,以便您的代码成为Mapper.Map(user)

奖励积分

  1. 您可以跳过BLL.User这些private字段并将其转换为自动属性
  2. 您可以添加从ValidationAttribute派生的属性,以帮助在ASP.NET MVC应用程序中进行validation
 public class User { public string UserId { get; set; } [Required] public string FirstName { get; set; } public string LastName { get; set; } [Range(0, int.MaxValue)] public int Age { get; set; } [EmailAddress] public string EmailAddress { get; set; } } 

首先,不需要存储库层和数据访问层。 这两个层具有相同的目的 – 添加一个抽象层来处理持久存储。 虽然他们有不同的概念

  1. 存储库模式基本上为您提供了一种使用数据库的方法,就像它是内存集合一样。 大多数情况下,它暴露了基本的CRUD(创建读取更新和删除)方法以及其他一些扩展,例如GetAll方法等。 这是一个非常简化的描述,但是有足够的资源来解释这种模式
  2. 数据访问层也增加了抽象,但更加主观。 基本上它包含用于访问数据库的所有API。 例如,对于您的User类,它可以有GetUserByNameGetUserByIdRemoveUserGetAllActiveUsers等方法。

另外,工作单元不必在Repository / DAL中实现。 由于单个工作单元可以包含对多个实体的修改或对外部服务的请求。 在我看来,BLL将是一个更适合UoW的地方,因为在大多数情况下你可以看一个单一的商业行为(BL中的方法)作为UoW

现在,这有点清楚( 希望 )。 您的Repository / DAL应仅返回Business实体而不是数据库生成的类(如果它们不同),并且所有映射逻辑都应该封装在Repository / DAL层中。 例如, GetUserById方法应返回BLL - User Class而不是在这种情况下由EF生成的用户类,它可以是Repository / DAL层的内部类。

为了处理这些类之间的映射,您可以使用不同的库,如ValueInjecter或AutoMapper ,这些库非常棒,可以使您的开发更容易。