最近我被“模型”搞糊涂了。假设我们在数据库中有一个名为“Users”的表,其中包含4个列,在数据层面我有一个对应的“User”模型。
namespace MyProject.Data
{
public class User
{
public int Id { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public int UserType { get; set; }
}
}
在用户注册页面中,通常我会使用一个名为“User”(或您可以将其命名为UserRegistration)的视图模型。
namespace MyProject.Web
{
public class User
{
public string UserName { get; set; }
public string PlainTextPassword { get; set; }
}
}
此外,我们可能有一个用户个人资料页面,对应的视图模型名为“User”或“UserProfile”,它们具有非常相似的属性(但不完全相同)。 第一个问题:上述用户模型是相似的,正确的设计方式是什么?
- 将它们分别放在不同的独立类中。这是我目前正在做的事情,但一些属性是共同的,我需要手动设置值(或使用类似AutoMapper的工具)。
- 在它们之间进行共享/继承。看起来“共同属性”得到了共享,在不同的“User”模型中没有“UserName”属性。然而,在注册页面的视图模型中却很奇怪,因为它有名为“Password”和“PlainTextPassword”的属性,甚至还有“UserType”,但实际上只设置了UserName和PlainTextPassword。
[HttpPost]
public ActionResult Register(User user)
{
//only user.UserName and user.PlainTextPassword are useful
//however you will have user.Password, user.UserType with default values
//it even breaks the validation if you use ModelState.IsValid
}
看起来选项1更好?如果我错了或者你有其他想法,请纠正我。接下来基于选项1又出现了另一个问题。
第二个问题 我们有MyProject.Web.User作为视图模型和MyProject.Data.User作为数据模型。注册页面将一个MyProject.Web.User实例发送到我的控制器,最终我需要通过MyProject.Data.User将其保存到数据库中。应该是这样的:
//the controller in the web project
[HttpPost]
public ActionResult Register(User user)
{
UserManager.Register(user.UserName, user.PlainTextPassword);
//blabla
}
//UserManager in the business layer
public void Register(string userName, string plainTextPassword)
{
//validation
//set properties to MyProject.Data.User
//save the changes to db (probably via EF)
}
如果添加更多的属性,例如 string address, string mobile
,你会发现 UserManager.Register 的签名变得越来越长。我认为这里需要一个“用户”模型。MyProject.Web.User位于Web中,因此不能在 UserManager
中使用它。而 MyProject.Data.User 位于数据层,如果我们在这里使用 MyProject.Data.User,则 MyProject.Web 项目需要添加对 MyProject.Data 的引用,但是当前的引用关系是 UI->Core(业务逻辑)->Data。那么正确的设计是什么呢?