Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Web API动态LINQ搜索_C#_Asp.net_Linq_Asp.net Web Api_Iqueryable - Fatal编程技术网

C# Web API动态LINQ搜索

C# Web API动态LINQ搜索,c#,asp.net,linq,asp.net-web-api,iqueryable,C#,Asp.net,Linq,Asp.net Web Api,Iqueryable,我有一个对象BookData: public class BookData { public BookData(); public string[] Authors{ get; set; } public string Genre { get; set; } public int BookId { get; set; } public int PublishedDate{ get; set; } public string Title { get

我有一个对象BookData:

public class BookData
{
    public BookData();

    public string[] Authors{ get; set; }
    public string Genre { get; set; }
    public int BookId { get; set; }
    public int PublishedDate{ get; set; }
    public string Title { get; set; }
}
我正在尝试实现一个函数,在这个函数中,我可以通过book对象中的任何属性/字段进行搜索

例如,返回发布日期为2016且类型为“Thriller”的所有书籍。由于搜索字段的数量可能不同,如何创建动态搜索方法。例如,我可以使用所有字段或仅使用一个字段进行搜索

 public IList<BookData> SearchBookBy( arguments ) {   

 //return list of books which match the search criteria
 //e.g. Title contains "love" AND Genre="Romance" AND PublishDate=2015
 }
public IList SearchBookBy(参数){
//返回符合搜索条件的书籍列表
//e、 g.标题包含“爱情”和“浪漫”以及PublishDate=2015
}
到目前为止,我有这样的想法:

public IList<BookData> ListBooksBy(string title, string genre, int publishedDate, int bookId, string author)
    {
        var books = ListAllBooks();
    var bk = from m in books
             select m;

    bk = books.Where(
         (s =>
                   (s.Title.ToUpper().Contains(title.ToUpper()))
                || (s.BookId.ToString().Contains(bookId))
                || (s.Genre.ToUpper().Contains(genre.ToUpper()))
                || (s.PublishedDate.ToString().Contains(publishedDate))
                || (s.Authors.ToString().Contains(author))
            )).ToList();

    books. bk.ToList();
    return books;
}
@Authors VARCHAR(50) = NULL,
@Genre VARCHAR(50) = NULL,
@BookId VARCHAR(50) = NULL,
@PublishedDate VARCHAR(50) = NULL,
@Title VARCHAR(50) = NULL
public IList ListBooksBy(字符串标题、字符串类型、int publishedDate、int bookId、字符串作者)
{
var books=ListAllBooks();
var bk=从账簿中的m开始
选择m;
bk=书籍。在哪里(
(s=>
(s.Title.ToUpper().Contains(Title.ToUpper()))
||(s.BookId.ToString()包含(BookId))
||(s.Genre.ToUpper().Contains(Genre.ToUpper()))
||(s.PublishedDate.ToString().Contains(PublishedDate))
||(s.Authors.ToString().Contains(author))
)).ToList();
books.bk.ToList();
还书;
}
但上述情况并不是动态的,肯定有更好/更干净的方法可以做到这一点

如果你能帮忙,我将非常感激,因为我对这方面还很陌生


提前感谢。

如上面评论中所述,您可以使用表达式树来完成此操作。它可以做您需要做的事情,但可能不完全可行,这取决于数据集的大小;如果使用表达式树,则在内存中进行过滤,如果使用大型数据集,则可能会导致性能问题

另一种选择是在存储过程中进行过滤。例如,使用SQL Server,您可以将参数默认为NULL,如下所示:

public IList<BookData> ListBooksBy(string title, string genre, int publishedDate, int bookId, string author)
    {
        var books = ListAllBooks();
    var bk = from m in books
             select m;

    bk = books.Where(
         (s =>
                   (s.Title.ToUpper().Contains(title.ToUpper()))
                || (s.BookId.ToString().Contains(bookId))
                || (s.Genre.ToUpper().Contains(genre.ToUpper()))
                || (s.PublishedDate.ToString().Contains(publishedDate))
                || (s.Authors.ToString().Contains(author))
            )).ToList();

    books. bk.ToList();
    return books;
}
@Authors VARCHAR(50) = NULL,
@Genre VARCHAR(50) = NULL,
@BookId VARCHAR(50) = NULL,
@PublishedDate VARCHAR(50) = NULL,
@Title VARCHAR(50) = NULL
然后在where子句中筛选:

WHERE   (Authors LIKE @Authors OR @Authors IS NULL)
AND     (Genre LIKE @Genre OR @Genre IS NULL)
AND     (BookId LIKE @BookId OR @BookId IS NULL)
AND     (PublishedDate LIKE @PublishedDate OR @PublishedDate IS NULL)
AND     (Title LIKE @Title OR @Title IS NULL)
这就产生了一些丑陋的SQL,您可能应该清理数据类型,但您明白了。对于大量的搜索参数来说,走SQL路线并不是真正可持续的

如果您决定采用表达式树路线,我有一个为演示文稿编写的演示项目,您可以将其用作起点:


希望这能有所帮助

您最好的选择是实现动态过滤,或者动态过滤的方法是搞乱表达式树:您可以使用过滤器获得对象,并根据其属性构建表达式树。我不认为有现成的解决方案,除了OData Controllers。您应该拆分查询以提高性能,方法是在实际查询中使用(添加)参数之前对每个参数进行null检查。另外,您不需要动态查询生成器,因为您没有动态模型(即BookData属性在运行时不会更改(只有它们的值,但没有其他更改),您似乎肯定要重新创建OData。