铸造/映射代表

问题描述:

我有一个方法铸造/映射代表

public List<DTO.User> GetUsers(Func<Domain.User, bool> expression) 
    { 
     var users = new List<DTO.User>(); 

     using(UserContext context = new UserContext()) 
     { 
      // obviously an error 
      users = context.Users.ToList(); 
     } 

     return users; 

    } 

通知的DTO.User(一个DTO)和Domain.User(从EF域实体) 因此,我使用AutoMapper映射这样

实体
public List<DTO.User> GetUsers() 
    { 
     var users = new List<DTO.User>(); 

     using(UserContext context = new UserContext()) 
     { 

      Mapper.CreateMap<Domain.User, DTO.User>(); 
      users = 
      Mapper.Map<List<Domain.User>,List<DTO.User>>(context.Users.ToList()); 
     } 

     return users; 

    } 

好的,这看起来不错,但是..我想让GetUser方法接受委托表达式作为参数。我在UI中有一个显示用户列表的网格,它有很多过滤选项,所以我希望我的UI只调用1个方法,而不是每个过滤器都创建方法。

// filter by username 
    List<DTO.User> users = userBL.GetUsers(u => u.UserName.Contains(txtUserName.Text)); 

    // filter by ID 
    List<DTO.User> users = userBL.GetUsers(u => u.== txtUserID.Text); 

    ... 

所以我在DAL层想出了这样的理念

public List<DTO.User> GetUsers(Func<DTO.User, bool> expression) 
    { 
     var users = new List<DTO.User>(); 

     using(UserContext context = new UserContext()) 
     { 
      Mapper.CreateMap<Domain.User, DTO.User>(); 

      Func<Domain.User, bool> predicate; 

      // this is an error on AutoMaper 
      predicate = Mapper.Map<Func<DTO.User,bool>, Func<Domain.User, bool>>(expression) 

      // I also tried direct casting which is an obvious fail 
      //predicate = (Func<Domain.User,bool>)expression; 

      users = 
      Mapper.Map<Domain.User, DTO.User>(context.Users.Where(predicate).ToList()); 
     } 

     return users; 

    } 

所以基本上,我想投或映射DTO委托域名delaget为它在使用domain.User列表的.Where()方法。可能吗?提前致谢。

+0

任何人的一些详细信息...? – dotnetlinc 2011-05-06 07:49:39

+0

我想转换一个Func是不可能的,因为它包含编译语句,但是你可以接受一个表达式而不是一个Func;这样你可以得到一个抽象的语法树,你可以在其上执行转换。然而,这是错误容易和繁琐,除非你有很少的预期条件。 – faester 2011-05-06 07:52:53

+0

我只希望过滤条件.Where() – dotnetlinc 2011-05-06 08:01:02

我几乎可以肯定,你不能代表映射到另一个代表,但你的代码有更多的问题:

  • 如果传递Func<User, bool>到您的LINQ到实体查询,你会做你一样现在做。它将从数据库中提取所有数据并在应用程序服务器的内存中执行过滤器。您必须通过Expression<Func<User, bool>>才能在DB服务器上执行它。
  • 我不知道整个架构和应用程序的复杂性,但我觉得直接在DAL中转换为DTO并不好。当使用EntityObjects时,我可以想象只在EFv1中这样做。
+0

我的目标不是从数据库中提取所有数据,当过滤时,为什么我在UI中有我的谓词,GetUser(u => u.ID == ID)应该等价于select *从ID = @ID的用户...但是如你所说,我必须学习Expression 来做到这一点,谢谢 – dotnetlinc 2011-05-06 07:53:43

+0

回到问题,我该如何转换Expression >表达式>? – dotnetlinc 2011-05-06 07:55:03

+0

Yah,我也在考虑移动BL中的DTO转换 – dotnetlinc 2011-05-06 07:56:32

如果你还在为铸造的代表,你可以找到有关here.