问题
I have a method
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;
}
Notice the DTO.User (a DTO) and Domain.User (a domain entity from EF) So I use AutoMapper to map entities like this
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;
}
Alright, this looks OK but.. I want the GetUser method to accept a delegate expression as a parameter. I have a grid in the ui that displays the user list and it has many filtering options, so I want my UI to just call 1 method instead of creating method per filter.
// 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);
...
So I came up with the Idea like this in my DAL layer
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;
}
So basically, I'm trying to cast or map the DTO delegate to Domain delaget for it to be use in the .Where() method of the domain.User list. Is it possible? thanks in advance.
回答1:
I'm almost sure that you cannot map delegate to another delegate but your code has even more problems:
- If you pass
Func<User, bool>
to your Linq-to-entities query you will do the same as you do now. It will pull all data from the database and execute filter in your application server's memory. You must passExpression<Func<User, bool>>
to execute it on DB server. - I don't know whole your architecture and complexity of the application but I feel that placing conversion to DTOs directly in DAL is not good. I can imagine doing this only in EFv1 when using
EntityObjects
.
回答2:
If you are still into casting delegates you can find some more info about that here.
来源:https://stackoverflow.com/questions/5908237/casting-mapping-delegates