自动映射器从列表映射返回0的计数?

时间:2011-12-14 16:07:27

标签: c# automapper

所以我在SO上发现了一些问题(例如:Automapper mapping list becomes 0)关于automapper从映射返回0的列表,但似乎没有一个我正在看的东西。

我有两种类型:

public class DNSContract : BaseContract
{
    public int DoNotSolicitID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
    public string Zip4 { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    public string BusinessName { get; set; }
    public string Partner { get; set; }
    public string Origination { get; set; }
}

public DNS_Entity()
    {
        // set default values which can be expicity set if needed
        InsertDT = DateTime.Now;
        InsertDT = DateTime.Now;
       // InsertUserID = 999;
        Origination = "RDI";
    }

    public long DoNotSolicitID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
    public string Zip4 { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    public string BusinessName { get; set; }
    public string Partner { get; set; }
    public string Origination { get; set; }
    public Nullable<System.DateTime> InsertDT { get; set; }
    //public int InsertUserID { get; set; }
    public DateTime? UpdateDT { get; set; }
    //public int UpdateUserID { get; set; }
}
那里很容易。这是我正在使用的“快速地图”方法:

 public static TToType QuickMap<TFromType, TToType>(this TFromType fromObject, TToType toObject)
        where TFromType : class
        where TToType : class, new()
    {
        // Look for an existing map, and if none is found add one.
        if (Mapper.FindTypeMapFor(typeof (TFromType), typeof (TToType)) == null)
        {
            Mapper.CreateMap(typeof (TFromType), typeof (TToType));
        }

        // Execute the auto map
        TToType map = Mapper.Map(fromObject, toObject);

        return map;
    }
到目前为止,我猜这么好。然而,

TToType map = Mapper.Map(fromObject, toObject);

什么都不做。问题是这个代码返回一个空的DNSContract它应该返回4(来自我的单元测试):

 using (var scope = dnsWork)
        {
            scope.Register(this);

            var one = WhereInternal(whereClause);
            var two = one.ToList();
            var three = two.QuickMap(new List<DNSContract>());
            return three;
            //return WhereInternal(whereClause).ToList().QuickMap(new List<DNSContract>());
        }

在调试时,为了理智,我把呼叫分成了一,二,三。所以基本上,我有一个List,想要返回一个List,那就失败了。

有效的方法是:

return Mapper.Map(two, new List<DNSContract>());

但是我想使用泛型方法,而不是在整个服务层中都有映射。

使用automapper,我是否需要对列表映射执行任何特殊操作?我认为这是我映射类型的问题,但由于某种原因,类型B的列表无法正常工作。

感谢。这已经让我烦恼了好几个星期了,有点忽略了它,但我需要尽快解决。

UPDATE#1 :根据要求,下面是其类的片段中的WhereInternal方法,该方法位于我的DAL中并从实体框架中提取:

 public abstract class EFRepository<T> : IRepository<T> where T : BaseEntity
{
    public IUnitOfWork UnitOfWork { get; set; }

    private IDbSet<T> _objectset;

    private IDbSet<T> ObjectSet
    {
        get { return _objectset ?? (_objectset = UnitOfWork.Context.Set<T>()); }
    }

    public IQueryable<T> WhereInternal(Expression<Func<T, bool>> expression)
    {
        return ObjectSet.Where(expression);
    }
}

我不认为它在上下文中非常重要,因为我转换为列表然后尝试映射。

1 个答案:

答案 0 :(得分:2)

首先,你的QuickMap方法的实现存在一个问题 - 如果你真的需要一个类型的话,我不知道你为什么要传递第二个参数。您也不是最简单的方法来执行映射。

其次,根据documentation,仅为简单类型注册映射,因此我将单独注册和映射。 以下是我提出的建议:

static class MapperHelper
{    
    static void Register<TSource, TDestination>()
    {
        var mapped = Mapper.FindTypeMapFor(typeof(TSource), typeof(TDestination));
        if (mapped == null)
        {
            var expression = Mapper.CreateMap<TSource, TDestination>();
        }
    }
    static TDestination QuickMap<TSource, TDestination>(this TSource source)
    {
         return Mapper.Map<TSource, TDestination>(source);
    }
}

用法:

//Registration
MapperHelper.Register<DNS_Entity, DNSContract>();
//Mapping
var result = WhereInternal(whereClause).ToList().QuickMap<IList<DNS_Entity>, IList<DNSContract>>();