我正在尝试过滤应用程序中显示的帖子。一切都按预期进行,但我有一个小问题。用户可以选择他所遵循的教育和专业。如何根据获得的数组进行过滤?我尝试过类似的方法,但是感觉很丑。如果在我的Filter类中设置更多数组,例如Language []。它将变得更加混乱。我可以做些简单的事吗?
public class Filter
{
public string[] Education { get; set; }
public string[] Profession { get; set; }
public int PageIndex { get; set; }
}
public PaginatedResults<Post> FilterPosts(Filter filter)
{
// Both Education and Profession arrays are empty, we just return all the posts
if(filter.Profession.Any(prof => prof == null) && filter.Education.Any(study => study == null)) {
var posts1 = _dbContext.Posts.AsEnumerable();
return _searchService.Pagination<Post>(posts1, filter.PageIndex);
}
else
{
// Can this be simplified? Sometimes the Education array is empty and sometimes Profession array. User can choose
IEnumerable<Post> posts = null;
if(filter.Profession.Any(prof => prof == null))
{
posts = _dbContext.Posts.Where(post => filter.Education.Contains(post.Education)).AsEnumerable();
}
else if(filter.Education.Any(study => study == null))
{
posts = _dbContext.Posts.Where(post => filter.Profession.Contains(post.Profession)).AsEnumerable();
}
else
{
posts = _dbContext.Posts.Where(post => filter.Profession.Contains(post.Profession) && filter.Education.Contains(post.Education)).AsEnumerable();
}
return _searchService.Pagination<Post>(posts, filter.PageIndex);
}
}
答案 0 :(得分:1)
可能有很多方法可以解决此问题。假设您希望保留您的方法(我认为这是完全有效的),则可以尝试以下步骤:
IQueryable
假设您使用实体框架,我相信_dbContext.Posts
已经实现了IQueryable
。由于LINQ不会立即执行,因此我们可以在枚举集合之前按顺序构建过滤条件:
posts = _dbContext.Posts.Where(post => filter.Education.Contains(post.Education) && filter.Education.Contains(post.Profession)).AsEnumerable();
// since you are implementing `AND` semantics for your filters, is easy to break down into series of `.Where()` calls
posts = _dbContext.Posts.Where(post => filter.Education.Contains(post.Education))
.Where(post => filter.Education.Contains(post.Profession))
.AsEnumerable(); // this should filter Posts by Education AND Profession as well as represent the result as IEnumerable. Should be functionally identical to the first statement
这将使您仅在需要时添加.Where
过滤器:
if (filter.Profession.Any()) // if Profession has elements
{
posts = posts.Where(post => filter.Profession.Contains(post.Profession)); // apply respective filter to posts, you may want to ensure you only compare against meaningful search terms by appplying `.Where(i => !string.IsNullOrWhiteSpace(i))` to it
}
if (filter.Education.Any()) // if Education has elements
{
posts = posts.Where(post => filter.Education.Contains(post.Education)).AsEnumerable(); // apply respective filter to posts
}
public PaginatedResults<Post> FilterPosts(Filter filter)
{
IQueryable<Post> posts = _dbContext.Posts;
if (filter.Profession.Any()) posts = posts.Where(post => filter.Profession.Contains(post.Profession));
if (filter.Education.Any()) posts = posts.Where(post => filter.Education.Contains(post.Education));
return _searchService.Pagination<Post>(posts.AsEnumerable(), filter.PageIndex);
}