我正在尝试在我的应用程序中实现业务层。原因是我的(遗留)数据库对于我们拥有的用例来说非常复杂。所以我要做的是以下内容
- 从数据库上下文中检索数据模型
- 将数据模型转换为业务模型
- 将其传递给我的控制器以供使用。
这非常适合检索对象,但更新它们总是给我带来问题。让我先给你(一些)我的代码(有点简化):使用系统;
/* The datamodel*/
public class DataModel
{
[Key]
public int Id { get; set; }
public double InterestRate { get; set; }
}
/*The business model */
public class BusinessModel
{
public int Id { get; set; }
public double InterestRate { get; set; }
public bool IsHighInterest()
{
return InterestRate > 10;
}
}
public class MyDbContext : DbContext
{
public MyDbContext() : base("connectionstring")
{
}
public DbSet<DataModel> DataModels { get; set; }
}
/* In reality I've got a repository here with a unit-of-work object instead of accessing the DbContext directly. */
public class BusinessLayer
{
public BusinessModel Get(int id)
{
using (var context = new MyDbContext())
{
var dataModel = context.DataModels.FirstOrDefault(x => x.Id == id);
BusinessModel = Transform(dataModel); //Do a transformation here
}
}
public void Update(BusinessModel model)
{
using (var context = new MyDbContext())
{
var dataModel = TransformBack(dataModel);
context.Entry<dataModel>.State = System.Data.Entity.EntityState.Modified;
context.SaveChanges();
}
}
}
显然这是行不通的,因为实体框架无法再跟踪数据模型的更改。我正在寻找一种可以做这些事情的设计模式。希望你们中的任何人都可以帮助我。实际上,数据模型要复杂得多,而业务模型也很简单,因此仅使用DataModel也不是一个真正的选择。
本质上是ViewModel模式。虽然您当然可以添加存储库,但请记住实体框架已经实现了工作单元,但我跑题了。我们中的许多人使用 POCO 实体模型执行与您的代码非常相似的事情,以与数据库进行交互,然后将其转换为 ViewModels、DTO 或您称之为业务模型。自动映射器非常适合此。
所以在我的更新代码中,我做了这样的事情(MVC):
if (ModelState.IsValid)
{
var entity = context.Entities.First(e => e.Id == viewmodel.Id); // fetch the entity
Mapper.Map(viewmodel, entity); // Use automapper to replace changed data
context.SaveChanges();
}
如果你可以访问Pluralsight,这里有一个关于这个主题的好视频:https://wildermuth.com/2015/07/22/Mapping_Between_Entities_and_View_Models