Я хотел бы использовать Automapper для сопоставления объектов моей модели с объектами базы данных. Пусть говорят, что объект базы данных - более 30 полей, и я хочу отобразить 10 из 20 свойств из моей модели. Чтобы сделать его более сложным, мне нужно сопоставить различные свойства при обновлении записи, чем когда я вставляю новую запись в базу данных.Использование Automapper для сопоставления больших моделей домена для объектов базы данных
Решение, которое я использую, состоит в том, чтобы создать 2 общих класса. Вставить и обновить и отобразить профиль, который задает оба сопоставления.
В приведенном ниже примере:
public abstract class SyncMappingWrapper<TFrom> where TFrom : class
{
protected SyncMappingWrapper(TFrom model)
{
Model = model;
}
public TFrom Model { get; private set; }
}
public class Update<TFrom> : SyncMappingWrapper<TFrom> where TFrom : class
{
public Update(TFrom model)
: base(model)
{
}
}
public class Insert<TFrom> : SyncMappingWrapper<TFrom> where TFrom : class
{
public Insert(TFrom model)
: base(model)
{
}
}
Отображение, однако, становится противным сложности цикломатической идет в небо (более 50), как мне нужно определить Игнорировать() для всех свойств я не карта:
CreateMap<Update<OracleModel>, LiveModel>()
.ForMember(des => des.ApprovedBy, opt => opt.Ignore())
.ForMember(des => des.ApprovedDate, opt => opt.Ignore())
...
.ForMember(des => des.UNSPSC, opt => opt.Ignore())
.ForMember(des => des.BaseUnit, opt => opt.MapFrom(src => src.Model.UOM.BaseUOM.PerSalesUnit))
.ForMember(des => des.BaseUOM, opt => opt.MapFrom(src => src.Model.UOM.BaseUOM.UnitOfMeasure.Code))
.ForMember(des => des.SalesUnit, opt => opt.MapFrom(src => src.Model.UOM.SalesUOM.PerSalesUnit))
.ForMember(des => des.SalesUOM, opt => opt.MapFrom(src => src.Model.UOM.SalesUOM.UnitOfMeasure.Code))
.ForMember(des => des.OrderUnit, opt => opt.MapFrom(src => src.Model.UOM.OrderUOM.PerSalesUnit))
.ForMember(des => des.OrderUOM, opt => opt.MapFrom(src => src.Model.UOM.OrderUOM.UnitOfMeasure.Code))
.ForMember(des => des.SalesPrice, opt => opt.MapFrom(src => src.Model.Price.Value))
.ForMember(des => des.Alternate, opt => opt.Ignore())
.ForMember(des => des.ManufacturerID, opt => opt.Ignore())
.ForMember(des => des.ProductCode, opt => opt.MapFrom(src => src.Model.ProductCode))
.ForMember(des => des.ProductName, opt => opt.MapFrom(src => src.Model.ProductName))
.ForMember(des => des.ProductHTML, opt => opt.Ignore())
.ForMember(des => des.Version, opt => opt.Ignore())
...
.ForMember(des => des.UnitsOfMeasure2, opt => opt.Ignore())
.ForMember(des => des.Manufacturer, opt => opt.Ignore());
Я решил эту проблему для вставки новой записи путем создания нового объекта:
CreateMap<Insert<OracleModel>, LiveModel>()
.ConstructUsing(x => new LiveModel
{
BaseUnit = x.Model.UOM.BaseUOM.PerSalesUnit,
BaseUOM = x.Model.UOM.BaseUOM.UnitOfMeasure.Code,
SalesUnit = x.Model.UOM.SalesUOM.PerSalesUnit,
SalesUOM = x.Model.UOM.SalesUOM.UnitOfMeasure.Code,
OrderUnit = x.Model.UOM.OrderUOM.PerSalesUnit,
OrderUOM = x.Model.UOM.OrderUOM.UnitOfMeasure.Code,
SalesPrice = x.Model.Price.Value,
LeadTime = x.Model.LeadTime,
ProductCode = x.Model.ProductCode,
ProductName = x.Model.ProductName,
SupplierCode = x.Model.SupplierCode,
Weight = x.Model.Weight
})
.ForAllMembers(xc => xc.Ignore());
Но это не работает для обновлений, где я хочу отобразить свойства существующего объекта и не новый экземпляр:
Mapper.Map(update, existingRecord);
Я бы предпочел, чтобы избежать DynamicMap(), чтобы сохранить полный контроль над отображением (так что я буду не сопоставить случайное свойство по ошибке). Моя цель - решить проблему циклической сложности. Пожалуйста, не предлагайте ValueInjecter или любые другие методы. Я ищу решение в AutoMapper.
вы когда-нибудь найти способ обойти это ? Я в том же квесте:/ –
Нет, я упростил свою модель. Тем не менее, я считаю, что ответ Thiago Sá должен работать для текущей версии AutoMapper. –