Мне любопытно узнать о наилучшей практике при разработке n-уровневого приложения с использованием Linq-to-SQL и службы WCF.
В частности, мне интересно, например, как вернуться к данным уровня представления из двух связанных таблиц. Предположим, следующая ситуация (очень упрощенная):
В базе данных есть таблицы:
Orders
(id, OrderName
)
OrderDetails
(id, orderid, DetailName
)
Средний уровень имеет методы CRUD для OrderDetails
. Итак, мне нужно иметь способ перестроить сущность для присоединения к контексту для обновления или вставки, когда она возвращается из уровня представления.
В слое презентации мне нужно отобразить список OrderDetails
с соответствующим OrderName
из родительской таблицы.
Существует два подхода для классов, которые возвращаются из сервиса:
Используйте пользовательский класс 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();
}
Минусы: необходимо назначить каждому полю, что важно для уровня представления обоими способами (при возврате данных и при создании нового объекта для присоединения к контексту, когда данные возвращаются с уровня представления)
Использовать настроенный частичный класс сущности 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, хотя мне нужно только одно поле из нее.
Извините за такую длинную историю. Может быть, я что-то пропустил? Буду признателен за любые предложения.