LINQ多关键字搜索到PagedList
LINQ multiple keyword search to PagedList
我在这里有点迷路,我尝试了几种不同的方法来解决它。到目前为止,我很难写出 LINQ 来做我想做的事。
我想获取用户输入的字符串,它可以是多个关键字,可以用空格或“,”分隔。
这里的作品抓取整个搜索词并将其与 Post 中的标题或我可能拥有的任何标签进行比较。我希望用户输入 "HTML Preview",这将匹配一个名为 post 的 "Preview the World" 和标签 "HTML"、"CSS" 等....
此查询将不起作用...但我正在尝试对其进行修改以使其起作用。
public IPagedList<Post> SearchResultList(string searchTerm, int resultsPerPage, int page)
{
string[] terms = searchTerm.Split(null);
TNDbContext context = DataContext;
return context.Posts
.Include(a => a.Tags)
.Include(b => b.Comments)
.Where(c => (c.Title.Contains(searchTerm) || c.Tags.Any(d => d.Name.StartsWith(searchTerm))) || searchTerm == null)
.OrderByDescending(x => x.Views)
.ToPagedList(page, resultsPerPage);
}
我试着写这个而不是其他 "Where" 语句
.Where(x => (terms.All(y => x.Title.Contains(y))) || terms == null)
但它一直抛出这个错误
Cannot compare elements of type 'System.String[]'. Only primitive types, enumeration types and entity types are supported.
供参考:
public class Post
{
public Post()
{
Tags = new HashSet<Tag>();
Comments = new HashSet<Comment>();
}
public int Id { get; set; }
public string Title { get; set; }
public string UrlTitle { get; set; }
public DateTime Date { get; set; }
public DateTime DateEdited { get; set; }
public string Body { get; set; }
public string Preview { get; set; }
public string PhotoPath { get; set; }
public int Views { get; set; }
//Navigational
public ICollection<Tag> Tags { get; set; }
public ICollection<Comment> Comments { get; set; }
}
public class Tag
{
public Tag()
{
Post = new HashSet<Post>();
}
public int Id { get; set; }
public string Name { get; set; }
public int TimesTagWasUsed { get; set; }
//Navigational
public ICollection<Post> Post { get; set; }
}
您需要从基本查询开始,然后为每个搜索词不断添加 where
子句。试试这个:
TNDbContext context = DataContext;
//Create the base query:
var query = context.Posts
.Include(a => a.Tags)
.Include(b => b.Comments)
.OrderByDescending(x => x.Views);
//Refine this query by adding "where" filters for each search term:
if(!string.IsNullOrWhitespace(searchTerm))
{
string[] terms = searchTerm.Split(" ,".ToCharArray(),
StringSplitOptions.RemoveEmptyEntries);
foreach(var x in terms)
{
string term = x;
query = query.Where(post => (post.Title.Contains(term) ||
post.Tags.Any(tag => tag.Name.StartsWith(term))));
}
}
//Run the final query to get some results:
var result = query.ToPagedList(page, resultsPerPage);
return result;
您可以使用额外的 'from' 语句嵌套查询,所以这样的事情应该有效:
var list = (from post in context.Posts.Include(a => a.Tags).Include(b => b.Comments)
from term in terms
where post.Title.Contains(term) || post.Tags.Any(d => d.Name.StartsWith(term))
select post).OrderByDescending(x => x.Views);
我在这里有点迷路,我尝试了几种不同的方法来解决它。到目前为止,我很难写出 LINQ 来做我想做的事。
我想获取用户输入的字符串,它可以是多个关键字,可以用空格或“,”分隔。
这里的作品抓取整个搜索词并将其与 Post 中的标题或我可能拥有的任何标签进行比较。我希望用户输入 "HTML Preview",这将匹配一个名为 post 的 "Preview the World" 和标签 "HTML"、"CSS" 等....
此查询将不起作用...但我正在尝试对其进行修改以使其起作用。
public IPagedList<Post> SearchResultList(string searchTerm, int resultsPerPage, int page)
{
string[] terms = searchTerm.Split(null);
TNDbContext context = DataContext;
return context.Posts
.Include(a => a.Tags)
.Include(b => b.Comments)
.Where(c => (c.Title.Contains(searchTerm) || c.Tags.Any(d => d.Name.StartsWith(searchTerm))) || searchTerm == null)
.OrderByDescending(x => x.Views)
.ToPagedList(page, resultsPerPage);
}
我试着写这个而不是其他 "Where" 语句
.Where(x => (terms.All(y => x.Title.Contains(y))) || terms == null)
但它一直抛出这个错误
Cannot compare elements of type 'System.String[]'. Only primitive types, enumeration types and entity types are supported.
供参考:
public class Post
{
public Post()
{
Tags = new HashSet<Tag>();
Comments = new HashSet<Comment>();
}
public int Id { get; set; }
public string Title { get; set; }
public string UrlTitle { get; set; }
public DateTime Date { get; set; }
public DateTime DateEdited { get; set; }
public string Body { get; set; }
public string Preview { get; set; }
public string PhotoPath { get; set; }
public int Views { get; set; }
//Navigational
public ICollection<Tag> Tags { get; set; }
public ICollection<Comment> Comments { get; set; }
}
public class Tag
{
public Tag()
{
Post = new HashSet<Post>();
}
public int Id { get; set; }
public string Name { get; set; }
public int TimesTagWasUsed { get; set; }
//Navigational
public ICollection<Post> Post { get; set; }
}
您需要从基本查询开始,然后为每个搜索词不断添加 where
子句。试试这个:
TNDbContext context = DataContext;
//Create the base query:
var query = context.Posts
.Include(a => a.Tags)
.Include(b => b.Comments)
.OrderByDescending(x => x.Views);
//Refine this query by adding "where" filters for each search term:
if(!string.IsNullOrWhitespace(searchTerm))
{
string[] terms = searchTerm.Split(" ,".ToCharArray(),
StringSplitOptions.RemoveEmptyEntries);
foreach(var x in terms)
{
string term = x;
query = query.Where(post => (post.Title.Contains(term) ||
post.Tags.Any(tag => tag.Name.StartsWith(term))));
}
}
//Run the final query to get some results:
var result = query.ToPagedList(page, resultsPerPage);
return result;
您可以使用额外的 'from' 语句嵌套查询,所以这样的事情应该有效:
var list = (from post in context.Posts.Include(a => a.Tags).Include(b => b.Comments)
from term in terms
where post.Title.Contains(term) || post.Tags.Any(d => d.Name.StartsWith(term))
select post).OrderByDescending(x => x.Views);