Служба Linq-to-SQL и WCF - объекты передачи данных - PullRequest
5 голосов
/ 22 декабря 2011

Мне любопытно узнать о наилучшей практике при разработке n-уровневого приложения с использованием Linq-to-SQL и службы WCF.

В частности, мне интересно, например, как вернуться к данным уровня представления из двух связанных таблиц. Предположим, следующая ситуация (очень упрощенная):

В базе данных есть таблицы:

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

Средний уровень имеет методы CRUD для OrderDetails. Итак, мне нужно иметь способ перестроить сущность для присоединения к контексту для обновления или вставки, когда она возвращается из уровня представления.

В слое презентации мне нужно отобразить список OrderDetails с соответствующим OrderName из родительской таблицы.

Существует два подхода для классов, которые возвращаются из сервиса:

  1. Используйте пользовательский класс DTO, который будет инкапсулировать данные из обеих таблиц и проекций:

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

    Минусы: необходимо назначить каждому полю, что важно для уровня представления обоими способами (при возврате данных и при создании нового объекта для присоединения к контексту, когда данные возвращаются с уровня представления)

  2. Использовать настроенный частичный класс сущности Linq-to-SQL:

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

Минусы: запрос к базе данных будет включать все столбцы таблицы Orders, Linq-to-SQL материализует всю сущность Order, хотя мне нужно только одно поле из нее.

Извините за такую ​​длинную историю. Может быть, я что-то пропустил? Буду признателен за любые предложения.

Ответы [ 2 ]

3 голосов
/ 22 декабря 2011

Я бы сказал, использовать DTO и Automapper, не очень хорошая идея выставлять сущность БД как datacontract

1 голос
/ 22 декабря 2011

Требуется ли использование Linq to SQL для вас, или вы все еще на стадии проектирования, где вы можете выбирать технологии? Если самое последнее, я бы предложил использовать Entity Framework с Self Tracking Entities (STE). После того, как вы вернете сущность от клиента, все изменения клиента будут обрабатываться для вас автоматически STE, вам просто нужно будет вызвать Save. Включение связанных сущностей также легко: (...some query...).Orders.Include(c => c.OrderDetails)

...