简体   繁体   中英

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 will 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.

我最终选择了Lucene作为索引。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM