2

我有一个关于将从数据访问层中的数据库获得的值分配给 WCF 层的数据合同的正确方法的问题。

考虑一个简单的场景,从数据库中获取所有学生的列表,然后将其分配给学生数据合约。

我的学生数据合同如下所示:

[DataContract]
public class StudentDC
{

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

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

在我的数据访问类中,我会有一个像 List GetAllStudents() 这样的方法

我的问题是关于我的 GetAllStudents() 方法的实现。它看起来像下面这样是否可以:

  1. 公共列表 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. 我会有如下的学生业务对象类:

    公共课学生BO {

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

然后,学生业务对象中的值将被分配给服务合同实现中的学生数据合同,从那里通过线路发送出去。

以上两种方式哪一种是正确的方式?

4

2 回答 2

2

首先,您应该询问您的设计目标:

  • 您的数据库层对象多久更改一次(例如添加/更新/删除新字段)?
  • 数据层表多久更改一次(重新设计关系、表结构)?
  • 您的 WCF 域对象多久更改一次以满足业务/UI 要求?

将数据层与业务对象分离的主要思想是在它们之间进行某种程度的抽象。因此,持久层(又名:数据访问层)的变化不会对更高级别的业务逻辑产生重大的连锁反应。业务逻辑也是如此……如果有更改……对持久层的更改是最小的。

另一个方面是代码的可测试性。您可以为您的业务逻辑提供单元测试用例,并在没有连接到实际数据库的持久层的情况下运行它们。相反,您可以在持久层中使用“模拟”类,以便您可以在内存中运行所有内容并测试您的业务层,而无需连接到数据库。

最后,如果您不期望在您的应用程序的整个生命周期中更改任何一个层并维护不期望的代码,您可以使用它。但在大多数情况下,应用程序会发生变化,维护成本是关键点之一……而层松耦合在这里有很大帮助。

您还可以考虑使用AutoMapper将数据访问层和业务层对象之间的映射外部化

于 2013-03-28T14:47:58.357 回答
0

如果我理解正确,问题基本上是以下两个选项中哪个更“正确”:

  • 数据库数据对象 -> 数据传输对象
  • 数据库数据对象 -> 业务对象 -> 数据传输对象

我会说前者。您的业​​务对象的存在是为了封装应用程序业务域的逻辑,您的 DTO 的存在是为了帮助将数据从您的应用程序移动到其客户端。不仅从数据库对象复制到业务对象以及从那里复制到 DTO 需要付出更多的努力,而且有些人说(尤其是在命令-查询职责分离世界中)业务对象上的属性甚至不应该公开访问,因为这会暴露它们的属性内部状态并违反封装。所以是的——在我看来,直接从 ORM 数据库对象复制到 DTO 既好又更正确。

另外@user1697575 指出AutoMapper可以帮助您进行映射是非常正确的 :)

于 2013-04-02T15:25:55.533 回答