目前我正在建立一個使用sqlite的Windows應用程序。在數據庫中有一個表格,表示User
,在我的代碼中有Repository<User>
和UserManager
。我認爲這是一個非常普通的設計。在倉庫有一個List
方法:返回可查詢<T>或列表<T>存儲庫中<T>
//Repository<User> class
public List<User> List(where, orderby, topN parameters and etc)
{
//query and return
}
這帶來一個問題,如果我想要做一些複雜的UserManager.cs
:
//UserManager.cs
public List<User> ListUsersWithBankAccounts()
{
var userRep = new UserRepository();
var bankRep = new BankAccountRepository();
var result = //do something complex, say "I want the users live in NY
//and have at least two bank accounts in the system
}
可以看到,返回List<User>
帶來的性能問題,監守的查詢早於預期執行。現在我需要改變它的東西就像一個IQueryable<T>
:
//Repository<User> class
public TableQuery<User> List(where, orderby, topN parameters and etc)
{
//query and return
}
TableQuery<T>
是sqlite的驅動程序,這幾乎是EF等於IQueryable<T>
,它提供了一個查詢並不會立即執行的一部分。但現在的問題是:在UserManager.cs
中,它不知道什麼是TableQuery<T>
,我需要在業務層項目中添加新的引用和導入命名空間,如using SQLite.Query
。它確實帶來糟糕的代碼感覺。爲什麼我的業務層應該知道數據庫的細節?爲什麼業務層應該知道什麼是SQLite?什麼是正確的設計呢?
你能不能「僅僅」在業務層和數據訪問層之間添加抽象的一個新的圖層(接口)?是的,這需要一組代表業務層中相同數據的對象,並在DA層和DA層之間進行映射 - 從某種意義上說,代碼重複 - 但它應該讓您在各層之間有更清晰的切換,如果我正確理解你的情況。 – Kjartan
我同意@Kjartan,你真正想要的是IQueryable,可惜SQLite沒有一個,值得創建另一個層來轉移到正確的類型。 –
ivenxu
@Kjartan @ivenxu:我沒有說'TableQuery'不正確,也沒有'IQueryable '是正確的。即使我添加了一個新的傳輸接口,如'IQuery ',它仍然* *基於*'TableQuery ',並且當我在業務層中使用'IQuery '時,所有內容都是相同的。它只是*看起來*與SQLite無關,但事實上,它戴着面具。 –