在我的应用程序中,我总是使用数据库(实体框架)和MVC的不同模型来分离事物。我也将它们分为不同的项目:
- Example.Entities-包含我的EF实体和用于访问它们的数据库上下文。
- Example.Models-包含MVC模型。
- Example.Web -Web应用程序。同时取决于Example.Domain和Example.Models。
MVC模型不是像域实体那样保存对其他对象的引用,而是将ID作为整数保存。
当对页面的GET请求进入时,MVC控制器执行数据库查询,该查询返回一个实体。我编写了采用域实体并将其转换为MVC模型的“转换器”方法。还有其他方法则相反(从MVC模型到域实体)。然后将模型传递给视图,从而传递给客户端。
当发出POST请求时,MVC控制器将获得MVC模型。转换器方法将其转换为域实体。此方法还执行任何无法表示为属性的验证,并确保如果域实体已经存在,则我们将对其进行更新而不是获取新的。这些方法通常看起来像这样:
public class PersonConverter
{
public MyDatabaseContext _db;
public PersonEntity Convert(PersonModel source)
{
PersonEntity destination = _db.People.Find(source.ID);
if(destination == null)
destination = new PersonEntity();
destination.Name = source.Name;
destination.Organisation = _db.Organisations.Find(source.OrganisationID);
//etc
return destination;
}
public PersonModel Convert(PersonEntity source)
{
PersonModel destination = new PersonModel()
{
Name = source.Name,
OrganisationID = source.Organisation.ID,
//etc
};
return destination;
}
}
通过使用这些方法,我消除了在每个控制器中原本会发生的重复。使用泛型可以进一步消除重复数据。
用这种方式做事有很多好处:
- 您可以根据特定的视图或操作来自定义模型。假设您有一个人的注册表单,该表单在提交后会创建许多不同的实体(人,组织,地址)。如果没有单独的MVC模型,这将非常困难。
- 如果我需要向视图传递比仅在实体中可用的信息更多的信息,或者将两个实体组合到一个模型中,那么我的宝贵数据库模型就永远不会被触及。
- 如果您曾经将MVC模型序列化为JSON或XML,则只会获得序列化的直接模型,而不是链接到该模型的所有其他实体。