如何在n层架构中映射实体框架模型类和业务层类

本文关键字:框架 实体 模型 业务 映射 | 更新日期: 2023-09-27 17:49:37

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

DAL - User Model

[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> 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<App.DAL.Model.User> _user = new List<DAL.Model.User>();
        using (var _uow = new UserManagement_UnitOfWork())
        {
            _user = (from u in _uow.User_Repository.GetAll()
                     select u).ToList();
        }           
    }
}

我如何一起映射,其次;引用GetAllUser()方法,我仍然需要使用来自DAL的用户模型类,以便从数据库中获取所有用户,我目前的理解是;每一层应该是相互独立的,我有抽象层,即数据访问层和业务层之间的存储库。我对这两个概念一起工作有点困惑。我的思路是对的还是漏掉了什么。用户业务层也需要实际的答案

如何在n层架构中映射实体框架模型类和业务层类

你的问题更多的是关于设计/架构,它没有一个"一刀切"的解决方案。我最多只能分享一些建议,以及我通常在一个相当典型的ASP中会做什么。. NET MVC +实体框架栈:

1。确保你的BLL.User类遵循单一职责原则

你的BLL.User类不应该关注如何通过实体框架/工作单元从数据库检索DAL.User。你应该有另一个类/层来负责这个:

public interface IUserRepository
{
    IEnumerable<User> GetAllUsers();
}

然后另一个类来实现IUserRepository:

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

这样做消除了从BLL.UserUserManagment_UnitOfWork类的依赖,并促进了测试/模拟(即可以编写单元测试来模拟内存中的IUserRepository)

然后在控制器中,每当需要检索BLL.Users时,只需将IUserRepository的实例注入控制器的构造函数:

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

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

这实际上与第一点非常相似,你可以简单地使用另一个接口/类对:

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<DAL.User, BLL.User>(user)

加分

  1. 您可以跳过BLL.User中的private字段并将它们转换为自动属性
  2. 您可以添加从ValidationAttribute派生的属性,以帮助在ASP中进行验证。. NET MVC应用
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; }
}

您可以通过使用AutoMapper简单地做到这一点通过Nuget安装:

PM> Install-Package AutoMapper

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

Mapper.CreateMap<DAL.User, BLL.User>();

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

BLL.User bll_User = Mapper.Map<DAL.User, BLL.User>(dal_user);

首先,不需要存储库层和数据访问层。这两个层有相同的目的——为处理持久存储添加一个抽象层。尽管它们有不同的概念

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

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

现在更清楚一点了(希望是)您的Repository/DAL应该只返回业务实体,而不是数据库生成的类(如果它们不同),并且所有映射逻辑都应该封装在Repository/DAL层中。例如,GetUserById方法应该返回BLL - User Class而不是EF生成的User Class,后者可以是Repository/DAL层的内部类。

对于处理这些类之间的映射,你可以使用不同的库,如valueinjector或AutoMapper,它们真的很好,可以使你的开发更容易。