2

データ アクセス層のデータベースから取得した値を WCF 層のデータ コントラクトに割り当てる正しい方法について質問があります。

データベースからすべての学生のリストを取得し、それを学生データ コントラクトに割り当てる単純なシナリオを考えてみます。

私の学生データ契約は次のようになります。

[DataContract]
public class StudentDC
{

    [DataMember]
    public int StudentID { get; set; }

    [DataMember]
    public string StudentName { get; set; }
}

私のデータ アクセス クラスには、List GetAllStudents() のようなメソッドがあります。

私の質問は、GetAllStudents() メソッドの実装に関するものです。以下のような表示でよろしいでしょうか。

  1. public List GetAllStudents() {

    List<StudentDC> studentDCs = new List<StudentDC>();
    
    var students = db.Students_TB.Select(s => s).ToList();
    
    foreach(Student_TB student in students)
    {
        StudentDC studentDC = new StudentDC();
        studentDC.StudentID = student.StudentID;
        studentDC.StudentName = student.StudentName;
        studentDCs.Add(studentDC);
    }
    
    return studentDCs;
    

    }

データ コントラクトに値を割り当てる上記の方法は正しいですか、それとも、次のように、データ アクセス レイヤーでデータを受け入れてから、サービス コントラクト実装のデータ コントラクトに値を渡す学生ビジネス オブジェクト クラスを用意する必要があります。 :

  1. 次のような学生ビジネスオブジェクトクラスがあります。

    パブリック クラス StudentBO {

    int studentID;
    string studentName;
    
    public int StudentID
    {
        get { return studentID; }
        set { studentID = value; }
    }
    
    public <return type> BusinessLogicMethod1()
    {
        // Implementation
    }
    

    }

次に、データ アクセス レイヤーで、データベースから取得した値を学生ビジネス オブジェクトのコレクションに次のように割り当てます。

public List<StudentBO> GetAllStudents()

{

    List<StudentBO> studentBOs = new List<StudentBO>();

    var students = db.Students_TB.Select(s => s).ToList();

    foreach(Student_TB student in students)

    {
        StudentBO studentBO = new StudentBO();
        studentBO.StudentID = student.StudentID;
        studentBO.StudentName = student.StudentName;
        studentBOs.Add(studentBO);
    }

    return studentBOs;
}

学生ビジネス オブジェクトの値は、サービス コントラクト実装の学生データ コントラクトに割り当てられ、そこからネットワーク経由で送信されます。

上記の2つの方法のうち、正しい方法はどれですか?

4

2 に答える 2

2

最初に、設計目標を次のように尋ねる必要があります。

  • データベース層オブジェクトが変更される頻度はどのくらいですか (新しいフィールドの追加/更新/削除など)?
  • どのくらいの頻度でデータ層テーブルが変更されますか (関係の再設計、テーブル構造)?
  • ビジネス/UI 要件を満たすために WCF ドメイン オブジェクトが変更される頻度は?

データレイヤーをビジネスオブジェクトから分離する主なアイデアは、それらの間にある程度の抽象化を持たせることです。永続層 (別名: データ アクセス層) の変更が、より高いレベルのビジネス ロジックに大きな波及効果をもたらさないようにします。同じことがビジネス ロジックにも当てはまります...それに変更があったとしても...永続化レイヤーへの変更は最小限です。

もう 1 つの側面は、コードのテスト容易性です。ビジネス ロジックの単体テスト ケースを作成し、実際の DB に永続化レイヤーを接続せずに実行できます。代わりに、永続化レイヤーに「モック」クラスを用意して、すべてをメモリ内で実行し、DB に接続せずにビジネス レイヤーをテストできるようにすることができます。

最終的に、アプリのライフ サイクル全体でいずれかのレイヤーへの変更が予想されず、コードのメンテナンスが予想外である場合は、それを使用できます。しかし、ほとんどの場合、アプリには変更があり、メンテナンス コストは重要なポイントの 1 つです...そして、レイヤーの結合が大きな助けになります。

AutoMapperを使用して、データ アクセス レイヤーとビジネス レイヤー オブジェクト間のマッピングを外部化することも考えられます。

于 2013-03-28T14:47:58.357 に答える
0

私がそれを正しく理解していれば、質問は基本的に、次の2つのオプションのどちらがより「正しい」かということです:

  • データベース データ オブジェクト -> データ転送オブジェクト
  • データベース データ オブジェクト -> ビジネス オブジェクト -> データ転送オブジェクト

前者と申します。ビジネス オブジェクトはアプリケーションのビジネス ドメインのロジックをカプセル化するために存在し、DTO はアプリケーションからクライアントへのデータの移動を支援するために存在します。データベース オブジェクトからビジネス オブジェクトへのコピー、およびそこから DTO へのコピーはより多くの労力を必要とするだけでなく、(特にコマンド クエリ責任分離の世界では) ビジネス オブジェクトのプロパティはパブリックにアクセス可能であってはならないという人もいます。内部状態であり、カプセル化に違反しています。そうです - 私の意見では、ORM データベース オブジェクトから DTO に直接コピーすることは問題なく、より正確です。

また、@ user1697575 は、 AutoMapperを指摘してマッピングを支援するのはまったく正しいことです :)

于 2013-04-02T15:25:55.533 に答える