2

I have a question on the correct way to assign values obtained from the database in the data access layer to the data contracts at the WCF layer.

Consider a simple scenario in which to get a list of all students from the database and then assign it to a student data contract.

My student data contract looks like:

[DataContract]
public class StudentDC
{

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

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

In my data access class, I would have a method like List GetAllStudents()

My question is on the implementation of my GetAllStudents() method. Is it ok for it to look like the following:

  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;
    

    }

Is the above way of assigning values to the data contracts correct, or should I have student business object classes to accept the data in the data access layer, and then pass on the values to the data contracts in the service contract implementation, like the following:

  1. I would have student business object classes like the following:

    public class StudentBO {

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

    }

In the data access layer, I would then assign the values got from the database to a collection of student business objects as folows:

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

The values in the student business objects would then be assigned to the student data contracts in the service contract implementation, from where it would be sent out over the wire.

Which of the two ways above is the correct way?

user1697575
  • 2,830
  • 1
  • 24
  • 37
user1953684
  • 59
  • 1
  • 5
  • First thing I would ask is: will you be having a lot of business logic? Or would it be more like CRUD? – L-Four Mar 28 '13 at 14:59
  • In the first approach, I feel there is a higher amount of coupling between the data contracts and the data access layer, which may not be a good thing. – user1953684 Mar 28 '13 at 15:28

2 Answers2

2

First you should ask your design goals the following:

  • how often your data base layer objects change (e.g. add/update/delete new fields)?
  • how often data layer tables change (redesign of relations, table structure)?
  • how frequently your WCF domain objects change to satisfy business/UI requirements?

The main idea of separating data layer from your business objects is to have some level of abstraction between them. So that changes in the persistence layer(aka: data access layer) do not have major ripple effect on the higher level business logic. And the same goes with business logic...if there are changes to it...the changes to the persistence layer are minimal.

Another aspect is testability of your code. You can have unit test cases for your business logic and run them without persistence layer connected to an actual DB. Instead you could have "mock" classes in your persistence layer so that you can run all in memory and test your business layer with no connection to DB.

In the end, if you don't expect during entire life cycle of your app changes to either of the layers and maintenance of the code not expected, you could go with it. But in most cases, apps have changes and maintenance cost is one of the key points...and layer loos coupling is a big help here.

You could also think of externalizing your mapping between your data access layer and business layer objects by using AutoMapper

user1697575
  • 2,830
  • 1
  • 24
  • 37
0

If I've understood it correctly, the question is basically which is more 'correct' of the two following options:

  • Database data objects -> data transfer objects
  • Database data objects -> business objects -> data transfer objects

I would say the former. Your business objects exist to encapsulate the logic of the business domain of your application, your DTOs exist to help move data from your application to its clients. Not only is copying from database objects to business objects and from there to DTOs more effort, there are those that say (especially in the Command-Query Responsibility Segregation world) that properties on business objects shouldn't even be publically accessible as this exposes their internal state and violates encapsulation. So yeah - copying straight from ORM database objects to DTOs is both fine and more correct, in my opinion.

Also @user1697575 is quite right to point out AutoMapper to help you with your mapping :)

Steve Wilkes
  • 7,085
  • 3
  • 29
  • 32