在我的解决方案中,我有两个项目。一个是主要的 MVC4项目。另一个是 DataLayer项目,其中包含从现有数据库(稍后可能是某些存储库)生成的Entity Framework 5 edmx模型。
问题是pocos EF5生成位于DataLayer项目中。但我需要它们在MVC4项目的Models文件夹中。
我希望单独的DataLayer项目能够增加关注点的抽象和分离,但我无法弄清楚如何将这两个部分放在一起。
(我想在Models文件夹中保留另一层pocos,但这似乎不正确)
答案 0 :(得分:1)
我将你的项目分成两个,如你所描述的那样。
我想在Models文件夹中维护另一层pocos,但这似乎不正确
我想你会发现你最终会建立这个层。
这是两个项目 Project.Data 和 Project.Web 。 Project.Web有一个Project.Data的项目引用。
我的观点永远不会直接引用实体。我将使用AutoMapper将实体映射到DTO或ViewModels。这发生在我的 services 中,该 services 位于其自己的命名空间下的 Project.Web 中。我的服务永远不会返回实体类型,我的视图只使用ViewModels。
interface IFooService
{
FooDTO GetFoo(int id);
}
public class FooService : IFooService
{
public FooDTO GetFoo(int id)
{
var foo = dbContext.Foo.Where(f => f.Id == id).Select(f => new FooDTO {
Bar = f.Bar,
Blah = f.Blah
}).FirstOrDefault();
// I let AutoMapper take care of the mapping for me
var foo = Mapper.Map<FooDTO>(dbContext.Foo.Where(f => f.Id == id).FirstOrDefault());
return foo;
}
}
控制器操作:
public ActionResult FooDetails(int id)
{
FooViewModel foo = Mapper.Map<FooViewModel>(fooService.GetFoo(id));
return View(foo);
}
修改强> 添加花药模型层以映射Entity =&gt; DTO =&gt;查看模型
答案 1 :(得分:0)
这是存储库的工作。创建DTO类以保存视图友好模型,并使用存储库调用数据层并组装dto。然后可以专门为返回到客户端构建dtos,包括任何序列化或显示装饰等。这里没有什么复杂的。
我认为有些人的第一反应是“如果我必须创建这些课程,我会重复我的努力”,但你真的不是因为这些课程的目的不同,这正是你所说的,关注点的分离
public MyViewModel // model that is bound to the view
{
private UserRepository _userRepo;
public EmployeeDto ActiveUser {get;set;}
public MyViewModel()
{
_userRepo = new UserRepository();
LoadActiveUser();
}
private void LoadActiveUser()
{
var userId = (int)HttpContext.Current.Session["activeUser"] ?? 0;
if(userId > 0)
{
ActiveUser = _userRepo.GetEmployee(userId);
}
}
}
public UserRepository
{
private SomeEntityReference1 _myDal1;
private SomeEntityReference2 _myDal2; // maybe you need to make some other data layer call in order to fill this object out
public UserRepository()
{
_myDal1 = new SomeEntityReference1 ();
_myDal2 = new SomeEntityReference2 ();
}
public EmployeeDto GetEmployee(int id)
{
var empDto = new EmployeeDto();
// get employee
var dalEmpResult = _myDal.Employees.FirstOrDefault(e => e.EmployeeId == id);
empDto.FirstName = dalResult.FName;
empDto.LastName = dalResult.LName;
empDto.Id = dalResult.EmployeeId;
// get employee department info
var dalDeptResult = _myDal2.Departments.FirstOrDefault(d => e.DepartmentId == dalEmpResult.DeptartmentId);
empDto.DepartmentName = dalDeptResult.Name;
return empDto;
}
}
// client friendly employee object
[DataContract(Name="Employee")]
public class EmployeeDto
{
public int Id {get; internal set;}
[DataMember(Name="fname")]
[DisplayName("Employee First Name:")]
public string FirstName {get;set;}
[DataMember(Name="lname")]
[DisplayName("Employee Last Name:")]
public string LastName {get;set;}
public int DeptId {get;set;}
[DataMember(Name="dept")]
[DisplayName("Works at:")]
public string DepartmentName {get;set;}
}
我在这里展示两个不同的EF引用(你的数据库实体模式)的唯一原因只是为了说明这是你在返回FINISHED dto之前进行任何“额外”处理的机会,准备好消费。