首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Automapper将大域模型映射到数据库对象

使用Automapper将大域模型映射到数据库对象
EN

Stack Overflow用户
提问于 2010-09-14 23:31:34
回答 1查看 1.1K关注 0票数 3

我想使用Automapper将我的模型对象映射到数据库对象。假设数据库对象超过30个字段,我想从我的模型中映射20个属性中的10个。为了使其更加复杂,我需要在更新记录时映射不同的属性,而不是在数据库中插入新记录时映射。

我使用的解决方案是创建两个泛型类Insert和Update,以及指定这两个映射的映射配置文件。

示例如下:

代码语言:javascript
复制
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),映射变得越来越糟糕,因为我需要为所有没有映射的属性定义Ignore():

代码语言:javascript
复制
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());

我已经通过创建新对象解决了插入新记录的问题:

代码语言:javascript
复制
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());

但它不适用于我想要将属性映射到现有对象而不是新实例的更新:

代码语言:javascript
复制
        Mapper.Map(update, existingRecord);

我倾向于避免使用DynamicMap()来保持对映射的完全控制(这样我就不会错误地映射随机属性)。我的目标是解决圈复杂度问题。请不要建议使用ValueInjecter或任何其他方法。我正在寻找AutoMapper中的解决方案。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-06-10 19:37:44

五年后,这里有一个建议来降低这个映射的复杂性问题。您可以创建一个扩展,它将帮助您首先忽略所有成员:

代码语言:javascript
复制
public static class AutoMapperExtension {
    public static IMappingExpression<TSource, TDest> IgnoreAllMembers<TSource, TDest>(this IMappingExpression<TSource, TDest> expression) {
        expression.ForAllMembers(opt => opt.Ignore());
        return expression;
    }
}

然后使用它仅定义要执行的映射:

代码语言:javascript
复制
Mapper.CreateMap<Insert<OracleModel>, LiveModel>()
      .IgnoreAllMembers()
      .ForMember(d => d.BaseUnit, o => o.MapFrom(s => s.Model.UOM.BaseUOM.PerSalesUnit))
      /* Mapping for other members here. */;
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3710402

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档