2012-02-08 85 views
3

我正在嘗試構建一個解耦域模型。我的(抽象)域模型定義了一個實體,例如「Product」,然後我的具體SQL實現爲該實體提供了一個轉換方法。轉換Linq表達式的基類

例如:

public interface IDomainEntity<T> where T : class 
{ 
    T ToDomainEntity(); 
} 

我具體的SQL類,那麼實現該接口:

public partial class Product : IDomainEntity<Domain.Product> 
{ 
    public Domain.Product ToDomainEntity() 
    { 
     return new Domain.Product 
     { 
      ProductId = this.ProductId, 
      ... 
     }; 
    } 
} 

從我的產品領域的服務,我希望能夠揭露一般的過濾方法

public virtual IQueryable<T> Filter(Expression<Func<T, bool>> predicate) 
{ 
    return GetAll().Where(predicate); 
} 

在這種情況下,T的類型是Domain.Product。我遇到的問題是,在SQL存儲庫實現中,我需要將表達式從Domain.Product類型轉換爲Sql.Product類型,以便我可以將它用於我的Linq to Sql表。

是否有可能採取一個表達的基礎,並將其轉換爲另一種:

Expression<Func<Domain.Product, bool>> 

Expression<Func<Sql.Product, bool>> 

道歉提前如果這沒有意義。

回答

2

即使你想要做什麼是可能的,真正的問題應該是:會什麼做這個來得到什麼呢?

在我看來,Filter方法已經是一大漏洞漏泄的抽象。爲什麼過濾器輸入表達式?爲什麼它不只是一個「正常」的代表?我想到的唯一答案就是這是因爲表達式需要將謂詞從其當前形式映射到其他不是面向對象的東西。

因此,儘管進行了英勇的努力,API仍然表明底層實現旨在成爲關係型。換句話說,畢竟它並沒有如此解耦。使用the IQueryable return type is also problematic for similar reasons

+2

Hello Mark,我相信您可能會直接對我的困境負責,我正在閱讀您的書'依賴注入in。淨'。在意識到自己實際上是Mary Rowan的時候,上面的內容是通過我的努力來彌補的:-)我試圖做的是創建一種方法,讓消費者在獲取數據方面有更大的靈活性 - 我想我是試圖避免必須在域服務上創建太多的檢索方法(可能具有類似的簽名)。感謝您的指導 - 我會再次考慮。 – Neilski 2012-02-08 21:36:00

2

這是一個有趣的問題。如果predicate是一個仿函數而不是表達式,那麼翻譯將很簡單,但是您不會將表達式傳遞到生成的SQL中,而我收集的是您想要的(爲了效率)。

如果Sql.Product和Domain.Product有一個共同的接口,你可以使用,但我從你不想去這樣的問題收集。

我相信,無論是葉:1,「你不能這樣做」,或者2.「你必須走表達式樹和做翻譯自己。」 2.對你來說可能會或可能不太實際。

+0

我在大部分的實現中使用了泛型,所以我並不想介紹一個類特定的接口,儘管我也許可以在基類之上使用繼承來爲實現添加一個類特定的接口。重新定義表達式樹聽起來很有趣,所以將嘗試和研究,以查看它是否可能 - 感謝您的幫助 – Neilski 2012-02-08 18:47:21