3

在我的解决方案中,我有两个项目。一个是主MVC4项目。另一个是一个DataLayer 项目,它包含一个从现有数据库(以后可能还有一些存储库)生成的 Entity Framework 5 edmx 模型。

问题是 pocos EF5 生成位于 DataLayer 项目中。但我需要它们在 MVC4 项目的 Models 文件夹中。

我希望单独的 DataLayer 项目增加抽象和关注点分离,但我不知道如何将这两个部分放在一起。
(我想在 Models 文件夹中维护另一层 pocos 但这似乎不对)

4

2 回答 2

1

正如您所描述的,我将我的项目分为两个。

我想在 Models 文件夹中维护另一层 pocos 但这似乎不对

我想你会发现你最终会构建这个层。

这是两个项目Project.DataProject.Web。Project.Web 具有对 Project.Data 的项目引用。

  • Project.Data.Models:实体
  • Project.Web.Models:DTO、ViewModels

我的观点从不直接引用实体。我将使用 AutoMapper 将实体映射到 DTO 或 ViewModel。这发生在我的服务中,它位于自己的命名空间下的Project.Web中。我的服务从不返回实体类型,我的视图只使用 ViewModel。

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);
}

编辑: 添加花药模型层来映射实体 => DTO => 查看模型

于 2013-04-06T22:24:55.557 回答
0

这是存储库的工作。创建 DTO 类来保存视图友好的模型,并使用存储库来调用您的数据层并组装 dto。然后可以专门构建 dto 以返回给客户端,包括任何序列化或显示装饰等。这里没有什么复杂的。

我认为有些人的第一反应是“如果我必须创建这些类,我就是在重复我的努力”,但你真的不是,因为这些类服务于不同的目的,这正是你所说的,关注点分离。

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 以供使用之前进行任何“附加”处理的机会。

于 2013-04-06T23:27:33.110 回答