2013-06-20 19 views
4

我有一個存儲庫模式,我用它來通過EF訪問我的數據庫。這裏是我的功能之一:需要一個通用的存儲庫模式,需要兩個表引用和一個表達式

public IQueryable<T> Filter<T>(Expression<Func<T, bool>> predicate) 
     where T : class 
{ 
    return Context.Set<T>().Where<T>(predicate).AsQueryable<T>(); 
} 

我想要做的是使用類似的東西來實現以下功能:

from c in Context.Customers 
where !Context.Products.Any(p => p.ProductID == c.ProductID) 
select c; 

我需要這不只是工作的「客戶」和「產品「所以我需要一個通用的方法,如我的原始存儲庫功能所示。

---編輯---

我想這樣的事情後,我:

public IQueryable<T> Filter2<T, U>(Expression<Func<T,U, bool>> predicate) 
    where T : class 
    where U : class 
{ 
    return (Context.Set<T>().Where(
      !Context.Set<U>().Any(predicate))); 
} 

我要尋找到這樣調用該函數:

var result = _repository.Filter2<Products, Customers>((p, c) => p.ProductID == c.ProductID); 

- EDIT 2--

更多背景信息:

我需要檢查一個表中未在另一個表中引用的字段。我需要爲許多不同的表執行此操作,並且需要通過存儲庫服務訪問實體框架。我需要這樣做的通用函數,因爲我不想用表特定的函數填充存儲庫服務。我的要求是傳入一個表達式,該表達式定義檢查完成的方式以及引用表達式必須處理的兩個表的一些方法。

+1

爲什麼你不使用相同的功能,但否定了謂詞? – quantka

+1

我不確定你的意思。你可以把你需要的功能模型?它不需要使用正確的語法。 – tia

+0

我很努力地在你的特定例子中看到這個用例 - 爲什麼你不只是'p.ProductID!= c.ProductID'? – James

回答

2

我不確定爲什麼你覺得需要有一個通用的函數,它可以完成正常的Filter方法的逆過程。你只需要傳遞你需要的任何謂詞給一個Filter方法。應該沒有理由不能像傳入「in」謂詞那樣通過相同的方法來傳入「not in」謂詞。由於它看起來像CustomerProduct是兩個完全分離的實體(無導航屬性關係),因此您可能必須單獨獲取ProductId的集合才能在謂詞中使用。

實施例:(你在必要時存儲庫API在間隙填充)

var productRepository = new GenericRepository<Product>(); 
var productIds = productRepository.GetAll().Select(x => x.ProductId) 

var customerRepository = new GenericRepository<Customer>(); 

// ProductId is IN Products 
var customersInProducts = customerRepository.Filter(c => productIds.Contains(c.ProductId)); 

// ProductId is NOT IN Products 
var customersNotInProducts = customerRepository.Filter(c => !productIds.Contains(c.ProductId)); 

從IN在這種情況下唯一的區別和NOT IN是!

+0

如果你看看我的問題(第二編輯部分),我試圖更清楚地解釋我的要求。我的要求是傳入一個表達式並對兩個表運行該表達式。我不想硬編碼表格定義,所以我想在我的問題中使用泛型,因此。不幸的是,我原來的問題可能沒有使用我的表達最好的例子,因爲每個人似乎都認爲這個問題是關於有一個函數做一個正常的過濾器的逆。我敢肯定,如果不沿着表達式樹的路線走下去,我想做的事情是無法完成的。 – Retrocoder

+0

@Retrocoder我的解決方案不硬編碼表定義並使用通用的存儲庫方法。你可以用'Product'和'Customer'替換你想要的任何兩種類型的實體,並且它仍然可以工作,只要這個實例有兩個兼容的屬性,比如'ProductId'。我知道你想以某種方式進一步將這個邏輯進行通用化並將其封裝在存儲庫類中,但由於存儲庫通常與實體存在一對一的關聯,因此您可能會發現,如果沒有令人難以置信的尷尬,這並不容易。 – mclark1129

+0

雖然我開始使用CRUD的存儲庫模式,但是我想要做的更改使它更像是一個通用數據抽象層。經過一番實驗後,我清楚地知道,我想要做的是將數據庫訪問代碼保存在一個地方,但這種做法並不奏效。我想要一個調用存儲庫來返回我的結果,但我現在已經改變了我的方法。我現在做我需要做的兩個調用存儲庫和我的調用類中的一行Linq。 Linq正在研究IQueryables,因此我已經將數據訪問從我的veiwmodel類中分離出來了。 – Retrocoder