Linq-to-SQL and WCF Services - Data Transfer Objects

I'm interested in best practices when developing an n-tier application with Linq-to-SQL and WCF service.

In particular, I am wondering, for example, how to return presentation-level data from two related tables. Suppose the following situation (greatly simplified):

There are tables in the database:

  • Orders( id, OrderName)
  • OrderDetails( id, orderid, DetailName)

The middle tier has CRUD methods for OrderDetails. So, I need to have a way to rebuild the object to be context bound for the update, or insert when it returns from the view level.

In the view layer, I need to display a list OrderDetailswith the corresponding OrderNamefrom the parent table.

For classes returned from the service, there are two approaches:

  • Use a special DTO class that will encapsulate data from both tables and projections:

    class OrderDetailDTO
    {
      public int Id { get; set; }
      public string DetailName { get; set; }
      public string OrderName { get; set; }
    }
    IEnumerable<OrderDetailDTO> GetOrderDetails()
    {
      var db = new LinqDataContext();
      return (from od in db.OrderDetails
              select new OrderDetailDTO
              {
                Id = od.id,
                DetailName = od.DetailName,
                OrderName = od.Order.OrderName
              }).ToList();
    }
    

    Cons: you need to assign each field, which is important for the presentation level in both directions (when returning data and when creating a new object to be bound to the context, when data is returned from the presentation level)

  • Use an individual partial Linq-to-SQL object class:

    partial class OrderDetail
    {
      [DataMember]
      public string OrderName
      {
        get
        {
          return this.Order.OrderName    // return value from related entity
        }
        set {}
      }
    }
    
    IEnumerable<OrderDetail> GetOrderDetails()
    {
      var db = new LinqDataContext();
      var loadOptions = new DataLoadOptions();
      loadOptions.LoadWith<OrderDetail>(item => item.Order);
      db.LoadOptions = options;
      return (from od in db.OrderDetails
              select od).ToList();
    }
    

Cons: the database query will include all the columns from the table Orders, Linq-to-SQL materializes the entire Order object, although I only need one field.

Sorry for such a long story. Maybe I missed something? I will receive any suggestions.

+5
source share
2 answers

, DTO Automapper, DB datacontract

+3

Linq to SQL , ? , Entity Framework Self Tracking Entities (STE). , , STE, Save. : (...some query...).Orders.Include(c => c.OrderDetails)

+1

All Articles