2016-07-11 5 views
1

は、私は、オブジェクトBookDataを持っています。のWeb API、動的LINQの検索

たとえば、PublishedDate = 2016、Genre = "Thriller"のすべての書籍を返すことができます。検索フィールドの数が異なる可能性があるため、動的検索方法を作成するにはどうすればよいですか。例えば。私はすべてのフィールドまたはただ一つを使って検索することができます。

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; 
} 

しかし、上記は、動的ではなく、確かにこれを行うためのより良い/クリーンな方法があります:

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 
} 

これまでのところ、私はこのような何かを持っています。

私が非常に新しいことを助けることができれば非常に感謝します。

ありがとうございます。

+0

あなたの最善の策は[System.Linq.Dynamic](https://github.com/kahanu/System.Linq.Dynamic)または[LinqToQueryString](https://github.com/beyond-code-github)を実装することです。/LinqToQuerystring) –

+0

動的フィルタリングを行う方法は、式ツリーを使いこなすことです:フィルタを持つオブジェクトを取得し、そのプロパティに依存します式ツリーを構築します。 おそらくODataコントローラを除いて、この解決策はありません。 – Chizh

+1

実際のクエリで使用する前に引数をヌルチェックすることで、パフォーマンスを向上させるためにクエリを分割する必要があります。また、動的モデルを持たないため、動的なクエリビルダは必要ありません。つまり、BookDataプロパティは実行時に変更されません(その値のみですが、それ以外は何もありません)。 –

答えて

1

上記のコメントに記載されているように、これを式ツリーで行うことができます。それはあなたがしなければならないことをしますが、あなたのデータセットのサイズに応じて完全に実現可能ではないかもしれません。式ツリーを実行するとメモリ内のフィルタリングが行われ、大規模なデータセットがある場合はパフォーマンスの問題が発生する可能性があります。

もう1つの方法は、ストアドプロシージャでフィルタリングを行うことです。 SQL Serverを使用して、たとえば、あなたはこのようにNULLにパラメータをデフォルトすることができます

@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ルートに行くことは、多数の検索パラメータにとって、実際には持続可能ではありません。

を助け

Expression Trees

希望:

あなたは式ツリーのルートを行くことに決めた場合、私はあなたが出発点として使用することができるかもしれないのプレゼンテーションのために書いたデモプロジェクトを持っています