0

Item、ItemProductLine、および ProductLine の 3 つのドメイン モデルがあります。これらはそれぞれ、既存のデータベース テーブルにマップされます。ビューで使用するビューモデルもあります。

ドメイン モデル:

public class Item
{
    public string itemId { get; set; }
    public string itemDescription { get; set; }
    public float unitPrice { get; set; }
    // more fields
    public virtual ItemProductLine itemProductLine { get; set; }
}

public class ItemProductLine
{
    public string itemId { get; set; }
    public String productLineId { get; set; }
    // more fields
    public virtual ProductLine productLine { get; set; }
}

public class ProductLine
{
    public string productLineId { get; set; }
    public string productLine { get; set; }
    // more fields
}

モデルを見る:

public class ItemViewModel
{
    public string itemNumber { get; set; }
    public String itemDescription { get; set; }
    public Double unitPrice { get; set; }
    public string productLine { get; set; }
}

私の現在のクエリは次のとおりです。

from item in dbContext.Items
where unitPrice > 10
select new ItemViewModel()
{
    itemNumber = item.itemNumber
    itemDescription = item.itemDescription
    unitPrice = item.unitPrice
    productLine = item.itemProductLine.productLine.productLine
}

現在、コントローラーにこのクエリがありますが、コードをリファクタリングしています。クエリ コードをデータ アクセス層のリポジトリ クラスに配置したいと考えています。私が読んだことから、そのレイヤーのビューモデルを参照するべきではありません。に変更select new ItemViewModel()するとselect new Item()、次のエラーが返されます。

エンティティまたは複合型 'proj.DAL.Item' は、LINQ to Entities クエリでは構築できません。

私が見た解決策は、データ転送オブジェクト (DTO) を作成して、ドメイン モデルからビュー モデルにデータを転送することです。

ただし、これを行うと、データのコピーが 3 つになります。別のデータベース フィールドを追加して表示する必要がある場合は、3 つのファイルを更新する必要があります。私は DRY の原則に違反していると思います。DTO とビュー モデルを使用する場合、DRY 原則に違反することは避けられませんか? そうでない場合は、これをリファクタリングして DRY コードにする方法の例を提供できますか?

4

3 に答える 3

2

複数のモデルを持つことは DRY 違反ではありませんが、ドメイン モデルは持続性モデルと同じ (またはそれに基づいて構築されている、読み取り: 結合されている) ため、コードは関心の分離の原則に違反しています。モデルをレイヤごとに分けておき、automapper などのツールを使用してマッピングする必要があります。これにより、モデルが複数の目的を果たすことを防ぎます。

繰り返しているように見えますが、実際にはレイヤーを分離したままにして、コードの保守性を確保しています。

于 2014-01-24T18:09:09.063 に答える