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:
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:
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?
First you should ask your design goals the following:
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