Service Layer dynamic enough to allow for application to send over queries / filters?
We have our Data Access Layer setup to use repositories, services, and specifications (for predefined queries) . The service layer, when persisting data, takes in DTOs that get converted to actual entities before they are persisted. When requesting data we either get a single DTO or a collection of DTOs. The application layer only knows about the DTOs. It has no knowledge of the actual entities.
So a service and interface may look like this:
public class UserService: IUserService
{
IUserRepository _repository;
public UserService(IUserRepository repository)
{
_repository = repository
}
public UserDto GetByUsernameAndPassword(string username, string password)
{
return _repository.Find(UserSpecifications.MatchByUsernameAndPassword(username,password));
}
}
public interface IUserService: IBaseService<UserDto>
{
public UserDto GetByUsernameAndPassword(string username, string password);
}
Recently I have had the need to allow the application layer to generate a query to be passed into the service layer. Passing a string to do a find on an index or a single field is rather easy, it is when we want to perform sorts, filtering, and searches on an entity utilizing multiple fields that it becomes baffling to me.
Here are a couple scenarios:
A. Let's say we have a grid control on our application. That control allows us to sort on multiple fields. We need to pass that sort expression into the service, convert that expression to a list of properties on the entity to be passed to the repository. The repository knows how to handle multiple sorts on an entity collection.B. The application allows a user to construct a query based off fields in a DTO. The DTO looks likes this:
public class UserDto
{
string Username {get;set;}
string FirstName {get;set;}
string LastName {get;set;}
AddressDto Address{get;set;}
}
The query wi开发者_如何学Goll be constructed in a way where the user can select fields and provide terms: //This is and example of how the user may write a query in the system. Where Username SartsWith "A" AND Address.City = "Myrtle Beach"
So we may have an expression we send over to the Service:
u => u.Username.StartsWith("A") && u.Address.City == "Myrtle Beach"
I am trying to figure out the best way to convert some of these thoughts in the service. Has anyone else done anything like this?
I had thought about the application filtering the results from the service, but my concern is the result set could be huge. I only wanted to bring back what was needed from the database via the repositories.
I ended up going with Lucene for my index.
精彩评论