0

我的框架中有 DTOmodel。BLL 和 View 根本看不到 EntiyModel。我想在图层之间传输和转换复杂表达式。

这是BLL中的一个方法,像这样......

//// BLL(Service)
Public PersonDTO getAll(Expression<Func<PersonDTO, bool>> whereCondition)
{

   return _repository.getAll(whereCondition);

}


// DLL(Repository)

Public PersonDTO getAll(Expression<Func<PersonDTO, bool>> whereCondition)
{

   Expression<Func<Person, bool>> NewCondition = ?/ How Convert DTOwhereCondition ???

   return DataContext.Persons(NewCondition);

}

///// 我想像这样在 PersonDTO 上创建复杂的表达式:

var persons = serive.getPersons(i => i.PersonDetailsDTO.Count == 3);

///// 我的课程

     public class Person
       {
        public Int32 Id { get; set; }
        public String FirstName { get; set; }
        public String LastName { get; set; }
        public List<PersonDetail> PersonDetails { get; set; }
       }


    public class PersonDTO
      {
        public Int32 Id { get; set; }
        public String FirstName { get; set; }
        public String LastName { get; set; }
        public List<PersonDetailDTO> PersonDetailsDTO { get; set; }
      }
4

2 回答 2

0

这是最基本的解决方案。如果您需要更多功能,也许您可​​以从那里开始工作。到目前为止,它允许选择性地提供一个委托来解析映射的属性名称,但属性类型必须相同。

用法:

var mappedExpression =
    ExpressionMapper<Person>.MapFrom(originalDtoExpression, null);

// or:

var mappedExpression =
    ExpressionMapper<Person>.MapFrom(originalDtoExpression,
            entityPropertyName => someMapper.ResolveDtoPropertyName(entityPropertyName));

执行:

public class ExpressionMapper<TTarget> : ExpressionVisitor
{
    protected ExpressionMapper(Type sourceType, Func<string, string> resolveTargetMemberNameFunc)
    {
        this.SourceType = sourceType;
        this.ResolveTargetMemberNameFunc = resolveTargetMemberNameFunc ?? (cur => cur);
    }

    public Func<string, string> ResolveTargetMemberNameFunc { get; private set; }

    public Type SourceType { get; private set; }

    public static Expression MapFrom<TSource>(Expression sourceExpression, Func<string, string> resolveTargetMemberNameFunc)
    {
        return new ExpressionMapper<TTarget>(typeof(TSource), resolveTargetMemberNameFunc).Visit(sourceExpression);
    }

    public static Expression<Func<TTarget, bool>> MapFrom<TSource>(Expression<Func<TSource, bool>> sourcePredicateExpression, Func<string, string> resolveTargetMemberNameFunc)
    {
        return Expression.Lambda<Func<TTarget, bool>>(
                MapFrom<TSource>(sourcePredicateExpression.Body, resolveTargetMemberNameFunc),
                Expression.Parameter(typeof(TTarget), sourcePredicateExpression.Parameters[0].Name));
    }

    protected override Expression VisitMember(MemberExpression node)
    {
        var sourceMemberName = node.Member.Name;
        var targetNode = this.Visit(node.Expression);
        var targetMemberName = this.ResolveTargetMemberNameFunc(sourceMemberName);
        var targetMember = targetNode.Type.GetMember(targetMemberName).FirstOrDefault();

        if (targetMember == null)
        {
            throw new NotSupportedException(String.Format("The source type '{0}' cannot be mapped to the target type '{1}', because that target type has no member '{2}'.", node.Expression.Type.Name, targetNode.Type.Name, targetMemberName));
        }

        return Expression.MakeMemberAccess(targetNode, targetMember);
    }

    protected override Expression VisitParameter(ParameterExpression node)
    {
        if (node.Type == this.SourceType)
        {
            return Expression.Parameter(typeof(TTarget), node.Name);
        }

        return node;
    }
}
于 2012-06-30T13:01:31.367 回答
0

我使用 AutoMapper 将使用 DTO 的表达式转换为实体。表达式映射是 AutoMapper.Extensions.ExpressionMapping 包的一部分。当您调用 AddAutoMapper(它本身是 IServiceCollection 的扩展方法)时,您基本上必须调用 AddExpressionMapping

于 2021-11-01T05:09:01.460 回答