2014-02-18 126 views
2

我有一個類Bookstore,它實現了一個接口IBookstore通過接口搜索列表

Bookstore具有作爲私有財產的圖書列表:private List<Book> AllBooks;

我不想通過接口暴露的書籍的完整列表。相反,我希望用戶根據某些屬性查詢圖書。所以,在IBookstore我有以下幾點:

public interface IBookstore 
{ 
    IList<Book> SelectedBooks; 
} 
public class Bookstore : IBookstore 
{ 
    private List<Book> AllBooks; 
    public IList<Book> SelectedBooks { get; set; } 
} 

我希望做的是創建一個名爲SearchBooks的方法,將搜索包含各種屬性的所有條目列表AllBooks,然後設置SelectedBooks與結果。所以,我使用的是以下幾點:

Bookstore myStore = new Bookstore(); 
... 
myStore.SearchBooks(A BUNCH OF CRITERIA); 
myStore.SelectedBooks; // contains books selected by the criteria passed to SearchBooks above 

爲什麼我想這樣做:

  • 我將需要訪問SelectedBooks多次。我不想 多次運行搜索。
  • 我希望SelectedBooks的列表屬於myBookstore。此對象只創建一次並在很多地方使用,所以我希望能夠在許多地方訪問相同的SelectedBooks,而無需重新構建它。將其作爲當地財產存儲是不可取的;即,我不想做List<Book> myBooks = myStore.SearchBooks(A BUNCH OF CRITERIA);。我有一個很好的理由。

我的問題

鑑於Book有很多特性,例如Title,Author,Date等,什麼是最簡單的方法任意通過一組搜索條件SearchBooks,以便我可以在Bookstore私人搜索我的列表?

例如,如果我有權訪問應用程序中的整個列表,我可以使用Linq。我可以傳遞一個Linq查詢到一個方法並讓查詢在myBookstore內私下執行嗎?

+0

您是否考慮過按條件緩存搜索結果?如果內存不用擔心,那麼只需從'SearchBooks(...)'方法返回結果即可。 – Aaron

+0

@Aaron是的。我不想這樣做。 – Emily

+0

我不想緩存結果的原因是因爲我正在編寫Unity3D的代碼,並且在Unity中,我可以創建一個對象的實例並使其在多個級別和多個GameObjects中保持不變。如果我在查詢結果時緩存了結果,那麼結果會被限定在創建它們的GameObject中,如果我想將它們來回傳遞給其他GameObjects,那麼我必須編寫控制邏輯,或者我有重新執行查詢。我寧願將結果保存在'myBookstore'中,因爲我可以在任何地方訪問結果,而無需做任何額外的工作。 – Emily

回答

4

我可以將Linq查詢傳遞給方法並讓查詢在myBookstore中私下執行嗎?

您可以通過委託:

public void SearchBooks(Func<IEnumerable<Book>, IEnumerable<Book>> query) 
{ 
    SelectedBooks = query(AllBooks).ToList(); 
} 

調用示例:

myStore.SearchBooks(c => c.Where(b => b.Title == "test" && b.Author == "author")); 

或只是一組謂詞:

public void SearchBooks(params Func<Book, bool>[] predicates) 
{ 
    var query = AllBooks.AsEnumerable(); 
    foreach(var p in predicates) 
     query = query.Where(p); 

    SelectedBooks = query.ToList(); 
} 

調用示例:

myStore.SearchBooks(x => x.Title == "test", x => x.Author == "author"); 
+0

爲什麼他只是在方法內部進行查詢?有什麼特別的理由 – marko

+0

@marko是的,因爲我想將結果存儲在'myBookstore'中。我希望作爲myBookstore的一個屬性來獲取最近執行的查詢所產生的書籍列表。 – Emily

+0

Marcin,謝謝,我相信這正是我需要的。不過,我不太瞭解如何使用它。我將如何構造論據? – Emily

0

我個人不會經歷所有嘗試抽象查詢的概念的麻煩。相反,直接在圖書清單上使用LINQ。

您可以將書目列表作爲可枚舉序列公開。

public interface IBookstore 
{ 
    IEnumerable<Book> Books; 
} 

然後你可以通過任何你喜歡的方式通過LINQ查詢它。

IBookstore store; // Some store. 
var johngreenBooks = from book in store.Books 
        where book.Author == "John Green" 
        orderby book.Title 
        select book; 

如果您不想在每次枚舉時評估查詢,請將其設置爲列表或數組。

var johngreenBookArray = johngreenBooks.ToArray(); 

您可以傳遞這個數組(或列表),也可以將它放在某處。在我看來,我用來選擇某些書籍的查詢與書店無關,因此我不會將結果存儲在商店中。