3

私のソリューションには、2 つのプロジェクトがあります。1 つはメインのMVC4 プロジェクトです。もう 1 つは、既存の DB (および後でいくつかのリポジトリ) から生成された Entity Framework 5 edmx モデルを含む DataLayer プロジェクトです。

問題は、EF5 が生成する pocos が DataLayer プロジェクトにあることです。しかし、MVC4 プロジェクトの Models フォルダー内にそれらが必要です。

個別の DataLayer プロジェクトで関心の抽象化と分離を強化したいのですが、これら 2 つの部分を組み合わせる方法がわかりません。
(Models フォルダに pocos の別のレイヤーを維持することを考えましたが、これは正しくないようです)

4

2 に答える 2

1

あなたが説明するように、私は自分のプロジェクトを2つに分けています。

Models フォルダに別の pocos レイヤーを維持することを考えましたが、これは正しくないようです

最終的にこのレイヤーを構築することがわかると思います。

Project.DataProject.Webの 2 つのプロジェクトがあります。Project.Web には、Project.Data へのプロジェクト参照があります。

  • Project.Data.Models: エンティティ
  • Project.Web.Models: DTO、ViewModels

私のビューはエンティティを直接参照することはありません。AutoMapper を使用してエンティティを DTO または ViewModel にマップします。これは、独自の名前空間の下のProject.Webにある私のサービスで発生します。私のサービスは Entity 型を返さず、私のビューは 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 を組み立てます。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;}
}

ここで 2 つの異なる EF 参照 (データベース エンティティ スキーマ) を示す唯一の理由は、FINISHED dto を返す前に「追加の」処理を実行して、すぐに使用できるようにする機会であることを示すためです。

于 2013-04-06T23:27:33.110 に答える