Auto Mapper:如何映射表达式

时间:2015-05-13 07:42:44

标签: asp.net-mvc-5 automapper

 public IEnumerable<CustomBo> FindBy(Expression<Func<CustomBo, bool>> predicate)
    {
        Mapper.CreateMap<Expression<Func<CustomBo, bool>>, Expression<Func<Entity, bool>>>();

        var newPredicate = Mapper.Map<Expression<Func<Entity, bool>>>(predicate);

        IQueryable<Entity> query = dbSet.Where(newPredicate);

        Mapper.CreateMap<Entity,CustomBo>();

        var searchResult = Mapper.Map<List<CustomBo>>(query);

        return searchResult;
    }

我想将customBo类型映射到实体类型..

这里customBo是我的模型,Entity是来自edmx的数据库实体。

我正在使用AutoMapper。

我遇到以下错误

  

无法找到目标类型Data.Customer到源类型Model.CustomerBO的类型映射。使用CreateMap从源类型到目标类型创建映射。   无法找到从目标类型Data.Customer到源类型Model.CustomerBO的类型映射。使用CreateMap创建从源类型到目标类型的映射。

任何Suggession我在这里的任务...

谢谢

2 个答案:

答案 0 :(得分:0)

我找到了解决方法。我创建自定义方法来映射Expression。

public static class MappingHelper
{
    public static Expression<Func<TTo, bool>> ConvertExpression<TFrom, TTo>(this Expression<Func<TFrom, bool>> expr)
    {
        Dictionary<Expression, Expression> substitutues = new Dictionary<Expression, Expression>();
        var oldParam = expr.Parameters[0];
        var newParam = Expression.Parameter(typeof(TTo), oldParam.Name);
        substitutues.Add(oldParam, newParam);
        Expression body = ConvertNode(expr.Body, substitutues);
        return Expression.Lambda<Func<TTo, bool>>(body, newParam);
    }

    static Expression ConvertNode(Expression node, IDictionary<Expression, Expression> subst)
    {
        if (node == null) return null;
        if (subst.ContainsKey(node)) return subst[node];

        switch (node.NodeType)
        {
            case ExpressionType.Constant:
                return node;
            case ExpressionType.MemberAccess:
                {
                    var me = (MemberExpression)node;
                    var newNode = ConvertNode(me.Expression, subst);

                    MemberInfo info = null;
                    foreach (MemberInfo mi in newNode.Type.GetMembers())
                    {
                        if (mi.MemberType == MemberTypes.Property)
                        {
                            if (mi.Name.ToLower().Contains(me.Member.Name.ToLower()))
                            {
                                info = mi;
                                break;
                            }
                        }
                    }
                    return Expression.MakeMemberAccess(newNode, info);
                }
            case ExpressionType.AndAlso:
            case ExpressionType.OrElse:
            case ExpressionType.LessThan:
            case ExpressionType.LessThanOrEqual:
            case ExpressionType.GreaterThan:
            case ExpressionType.GreaterThanOrEqual:
            case ExpressionType.Equal: /* will probably work for a range of common binary-expressions */
                {
                    var be = (BinaryExpression)node;
                    return Expression.MakeBinary(be.NodeType, ConvertNode(be.Left, subst), ConvertNode(be.Right, subst), be.IsLiftedToNull, be.Method);
                }

            default:
                throw new NotSupportedException(node.NodeType.ToString());
        }
    }
}

现在我称之为

public CustomBo FindBy(Expression<Func<CustomBo, bool>> predicateId)
    {
        var newPredicate = predicateId.ConvertExpression<CustomBo, Entity>();
    }

如果有人知道如何通过automapper做到这一点,那么请告诉我。

由于

答案 1 :(得分:0)

在您提出问题后,似乎已添加此内容:Expression Translation (UseAsDataSource)

现在你需要做的就是dbSet.UseAsDataSource().For<CustomBo>().Where(expression).ToList();。好多了!