Linq搜索列表和链接的属性

时间:2016-09-21 07:46:48

标签: c# linq

我有一本书籍清单,每本书都有一个链接的作者。我的Api允许用户按标题或作者搜索。

在Api我有一个搜索模型

public class SearchOptions
{
    public string Title { get; set; }
    public string Author { get; set; }
}

用户可以同时使用这两个字段,也可以只使用标题或仅使用作者。

以下是我的书籍和作者模型

public class Book
{        
    public string Title { get; set; }
    public string Description { get; set; }
    public Author LinkedAuthor { get; set; }      
}

public class AuthorEntity
{
        public string FirstName { get; set; }
        public string LastName { get; set; }
}

我已经创建了以下Linq查询,但它不太正确,因为当作者没有完成时,即它是一个空白字符串,我得到了所有结果。

我几乎想说如果字符串不为null或为空,则为作者应用过滤器(和标题相同)但我不确定如何在Linq中执行此操作?

var returnedBooks = _bookRepository.GetAll()
            .Where(x => x.Title.Contains(title) ||
            (x.LinkedAuthor.FirstName + " " + x.LinkedAuthor.LastName).Contains(authorName)).ToList();

3 个答案:

答案 0 :(得分:2)

您可以通过逐个检查属性的值来创建查询的部分位置。如果用户输入任何标题,则为此属性添加过滤器。如果用户输入了作者姓名,则添加过滤器等等......

var books = _bookRepository.GetAll();

if (!String.IsNullOrEmpty(title))
    books = books.Where(x => x.Title.Contains(title));

if (!String.IsNullOrEmpty(authorName))
{
    books = books.Where(x => x.LinkedAuthor.FirstName.Contains(authorName) || x.LinkedAuthor.LastName.Contains(authorName));
}

答案 1 :(得分:0)

var returnedBooks = 
       from a in _bookRepository.GetAll() 
       where (
                  a.Title.Contains(title)) || 
                  ((a.LinkedAuthor.FirstName + " " + a.LinkedAuthor.LastName) != null 
                  && (a.LinkedAuthor.FirstName + " " + a.LinkedAuthor.LastName).Contains(authorName)
               ) 
         select a)
         .ToList();

答案 2 :(得分:0)

您可以检查每个查询字词并根据它们构造where子句。

我假设您收到了一个请求模型 - SearchOptions(包含您的查询字词):searchOptions

var books = _bookRepository.GetAll();

if (!string.IsNullOrEmpty(searchOptions.Title))
    books = books.Where(x.Title.Contains(searchOptions.Title));

if (!string.IsNullOrEmpty(searchOptions.AuthorName))
    books = books.Where((x.LinkedAuthor.FirstName + " " + x.LinkedAuthor.LastName).Contains(searchOptions.AuthorName));

另外,请确保在存储库_bookRepository.GetQueryable()中实现一个方法,为此类构造的where子句返回IQueryable。

然后您将实现以下内容:

var query = _bookRepository.GetQueryable();

if (!string.IsNullOrEmpty(searchOptions.Title))
   query = query.Where(x.Title.Contains(searchOptions.Title));

if (!string.IsNullOrEmpty(searchOptions.AuthorName))
   query = query.Where((x.LinkedAuthor.FirstName + " " + x.LinkedAuthor.LastName).Contains(searchOptions.AuthorName));

var books = query.ToList(); // or i don't know, just enumerate 

您可以在此处阅读更多内容:https://softwareengineering.stackexchange.com/questions/192044/should-repositories-return-iqueryable

还有一个关于动态where子句的参考:How do I implement a dynamic 'where' clause in LINQ?