views:

139

answers:

1

I have a business layer that has DTOs that are used in the presentation layer. This application uses entity framework.

Here is an example of a class called RoleDTO:

public class RoleDTO
{
    public Guid RoleId { get; set; }
    public string RoleName { get; set; }
    public string RoleDescription { get; set; }
    public int? OrganizationId { get; set; } 
}

In the BLL I want to have a method that returns a list of DTO. I would like to know which is the better approach: returning IQueryable or list of DTOs. Although I feel that returning IQueryable is not a good idea because the connection needs to be open. Here are the 2 different methods using the different approaches:

First approach

public class RoleBLL
{
    private servicedeskEntities sde;

    public RoleBLL()
    {
        sde = new servicedeskEntities();
    }

    public  IQueryable<RoleDTO> GetAllRoles()
    {
        IQueryable<RoleDTO> role = from r in sde.Roles
                        select new RoleDTO()
                        {
                            RoleId = r.RoleID,
                            RoleName = r.RoleName,
                            RoleDescription = r.RoleDescription,
                            OrganizationId = r.OrganizationId
                        };
        return role;
    }

Note: in the above method the DataContext is a private attribute and set in the constructor, so that the connection stays opened.

Second approach

public static List<RoleDTO> GetAllRoles()
{
    List<RoleDTO> roleDTO = new List<RoleDTO>();
    using (servicedeskEntities sde = new servicedeskEntities())
    {
        var roles = from pri in sde.Roles
                         select new { pri.RoleID, pri.RoleName, pri.RoleDescription };

        //Add the role entites to the DTO list and return. This is necessary as anonymous types can be returned acrosss methods
        foreach (var item in roles)
        {
            RoleDTO roleItem = new RoleDTO();
            roleItem.RoleId = item.RoleID;
            roleItem.RoleDescription = item.RoleDescription;
            roleItem.RoleName = item.RoleName;
            roleDTO.Add(roleItem);

        }
        return roleDTO;
    }
}

Please let me know, if there is a better approach.

+1  A: 

Its better not to send model objects directly to the presentation layer, you can have an intermediate layer where you map these DTO object to custom made objects that the presentation layer needs.

Which comes close to your second method, but not exactly the same.

Mahesh Velaga
Can you please be more clear about what is the problem with the first approach. Is it separation of concerns? I do prefer the second method but can you explain what is the exact way to do this?
samsur
There are 3 advantages with the method that I mentioned, first is seperation of concerns, second is almost all the times you presentation layer may not consume the whole of your DTO, so by tailor making your object for presentation layer allows u to send just enough info, third is you can just have validations etc done on you custom objects that u send to presentation layer rather than on DTO objects directly
Mahesh Velaga
To give an example, I generally work with ASP.NET MVC, I always create ViewModel Objects into which I copy the data that I need to send from the DTOs to the presentation layer and send the ViewModel objects to the presentation layer. I do validations on the ViewModel objects
Mahesh Velaga
Ok. I think there is a slight confusion here. The DTO contains properties that are tailor made for the presentation layer. Atleast, in my cast, thats how i have set it. The class RoleBLL is supposed to do exactly what you are saying. It will have a method called "GetAllRoles() and this is where validation/exception is handled as well.If you look at my other method, it returns iQueryable of the DTO. This is again shaped to match the requirements in presentation layer.(only the required fields are sent).
samsur