Я пытаюсь решить эту проблему, когда я использую Entity Framework (6) в приложении N-уровня. Поскольку данные из репозитория (который содержит всю связь с базой данных) должны использоваться на более высоком уровне (пользовательский интерфейс, службы и т. Д.), Мне нужно сопоставить его с DTO.Сопоставление объектов с DTO без дублированного кода
В базе данных существует довольно много взаимосвязей «многие-ко-многим», поэтому структура данных может/будет становиться сложной где-то вдоль линии срока службы приложений. Я наткнулся на то, что повторяю точный код при написании методов репозитория. Примером этого является мой FirmRepository
, который содержит метод GetAll()
и метод GetById(int firmId)
.
В методе GetById(int firmId)
, у меня есть следующий код (неполный, так как есть намного больше отношения, которые должны быть отображены на DTO):
public DTO.Firm GetById(int id)
{
// Return result
var result = new DTO.Firm();
try
{
// Database connection
using (var ctx = new MyEntities())
{
// Get the firm from the database
var firm = (from f in ctx.Firms
where f.ID == id
select f).FirstOrDefault();
// If a firm was found, start mapping to DTO object
if (firm != null)
{
result.Address = firm.Address;
result.Address2 = firm.Address2;
result.VAT = firm.VAT;
result.Email = firm.Email;
// Map Zipcode and City
result.City = new DTO.City()
{
CityName = firm.City.City1,
ZipCode = firm.City.ZipCode
};
// Map ISO code and country
result.Country = new DTO.Country()
{
CountryName = firm.Country.Country1,
ISO = firm.Country.ISO
};
// Check if this firm has any exclusive parameters
if (firm.ExclusiveParameterType_Product_Firm.Any())
{
var exclusiveParamsList = new List<DTO.ExclusiveParameterType>();
// Map Exclusive parameter types
foreach (var param in firm.ExclusiveParameterType_Product_Firm)
{
// Check if the exclusive parameter type isn't null before proceeding
if (param.ExclusiveParameterType != null)
{
// Create a new exclusive parameter type DTO
var exclusiveParameter = new DTO.ExclusiveParameterType()
{
ID = param.ExclusiveParameterType.ID,
Description = param.ExclusiveParameterType.Description,
Name = param.ExclusiveParameterType.Name
};
// Add the new DTO to the list
exclusiveParamsList.Add(exclusiveParameter);
}
}
// A lot more objects to map....
// Set the list on the result object
result.ExclusiveParameterTypes = exclusiveParamsList;
}
}
}
// Return DTO
return result;
}
catch (Exception e)
{
// Log exception
Logging.Instance.Error(e);
// Simply return null
return null;
}
}
Это только один метод. Тогда метод GetAll()
будет иметь точную топологию , которая приводит к дублированному коду. Кроме того, когда добавляется больше методов, то есть метод Find
или Search
, повторное копирование необходимо скопировать. Это, конечно, не идеально.
Я много читал о знаменитой структуре AutoMapper, которая может отображать объекты в/из DTO, но поскольку у меня есть эти отношения «многие-ко-многим», она быстро ощущается раздутой с помощью кода конфигурации AutoMapper. Я также прочитал эту статью, которая имеет смысл в моих глазах: http://rogeralsing.com/2013/12/01/why-mapping-dtos-to-entities-using-automapper-and-entityframework-is-horrible/
Есть ли другой способ сделать это без копирования и вставки одного и того же кода снова и снова?
Заранее благодарен!
Что вы пытаетесь достичь? Вы уверены, что должны возвращать объекты DTO вместо объектов? В чем смысл «переназначения» объектов на почти одни и те же объекты? – tdragon
Привет, tdragon, спасибо за ваш вклад. Когда я возвращаю объекты, то есть мои MVC-контроллеры, данные теряются, поскольку они не входят в область DbContext. Вот почему я собираю данные в DTO. Да? :-) –
проверить это, если это поможет http://stackoverflow.com/questions/13156437/mapping-a-dto-to-an-entity-with-automapper – NMK