如何在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的用户模型类,以便从数据库中获取所有用户,我目前的理解是;每一层应该是相互独立的,我有抽象层,即数据访问层和业务层之间的存储库。我对这两个概念一起工作有点困惑。我的思路是对的还是漏掉了什么。用户业务层也需要实际的答案
你的问题更多的是关于设计/架构,它没有一个"一刀切"的解决方案。我最多只能分享一些建议,以及我通常在一个相当典型的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.User
到UserManagment_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)
加分
- 您可以跳过
BLL.User
中的private
字段并将它们转换为自动属性 - 您可以添加从
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);
首先,不需要存储库层和数据访问层。这两个层有相同的目的——为处理持久存储添加一个抽象层。尽管它们有不同的概念
- Repository模式基本上为您提供了一种处理数据库的方法,就好像它是内存中的集合一样。大多数情况下,它暴露了基本的CRUD(创建、读取、更新和删除)方法以及一些其他扩展,如
GetAll
方法等。这是一个非常简化的描述,但是关于该模式有足够的资源,例如。 - 数据访问层也增加了一个抽象,但更主观的方式。基本上它包含了所有的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,它们真的很好,可以使你的开发更容易。