如何将MVC4与EF5 Db结合起来第一个单独的项目

时间:2013-04-06 20:57:35

标签: c# asp.net-mvc-4 entity-framework-5 ef-database-first

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

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

我希望单独的DataLayer项目能够增加关注点的抽象和分离,但我无法弄清楚如何将这两个部分放在一起。
(我想在Models文件夹中保留另一层pocos,但这似乎不正确)

2 个答案:

答案 0 :(得分:1)

我将你的项目分成两个,如你所描述的那样。

  

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

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

这是两个项目 Project.Data Project.Web 。 Project.Web有一个Project.Data的项目引用。

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

我的观点永远不会直接引用实体。我将使用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之前进行任何“额外”处理的机会,准备好消费。