2013-03-24 48 views
2

我正在使用實體框架和代碼。這裏有一個簡單的例子來向你展示我的情況。使用Linq表達式在通用存儲庫中執行搜索

public class PersonEfModel 
{ 
    public int Id { get; set; } 
    public string Vorname { get; set; } 
    public string Nachname { get; set; } 
} 

public class EfContext : DbContext 
{ 
    public DbSet<Person> Personen { get; set; } 
} 

要獨立於數據訪問的實現我寫了一個包含存儲庫的抽象層。

public class Person 
{ 
    public int Id { get; set; } 
    public string Vorname { get; set; } 
    public string Nachname { get; set; } 
} 

public interface IGenericRepository<T> 
{ 
    int Count { get; } 

    void Add(T item); 
    void Delete(T item); 
    void Update(T item); 

    T GetData(int id); 
    IEnumerable<T> GetData(); 
    IEnumerable<T> GetData(int offset, int count); 

    IEnumerable<T> Find(Expression<Func<T,bool>> predicate); 
    IEnumerable<T> Find(IEnumerable<Expression<Func<T, bool>>> predicates); 
} 

PersonPersonEfModel必須是兩種不同類型,以從數據庫模型完全獨立的。所以會有一個Person類型的通用Repository,但我真的不知道如何實現Find方法。我只能對依賴於PersonEfModel而不是Person的數據庫執行表達式。

那麼有沒有辦法將Expression<Func<Person, bool>>轉換爲Expression<Func<PersonEfModel, bool>>來對數據庫執行它還是我在錯誤的路徑上?

+2

您不需要創建2個對象來表示相同的實體。目前'Person'沒有底層數據訪問的概念 - 它已經獨立於數據庫模型。 – qujck 2013-03-24 22:32:15

+0

你實際面臨什麼問題?你嘗試過什麼嗎?如果是這樣,你可以分享一些代碼嗎? – ecampver 2013-03-25 04:42:00

+0

當你用EntityFrameworkContext加載一個實體,然後進行一些像Person.Name =「Test」這樣的更改時,看起來比下一次在上下文中調用SaveChanges人員名稱是「Test」時要好,因此實體框架正在跟蹤每個加載實體的更改。我實際上嘗試了一些東西(通過表達式樹和類似的東西),但沒有按預期工作。 – 2013-03-25 14:06:00

回答

1

如果您真的遵循域驅動設計,那麼您不需要創建2個獨立的對象來表示Person。您的Person類已經是POCO,它代表了您自己的代碼中所需的確切實體(您使用的是Code First)。

你只是引入了額外的和完全不必要的複雜性。每當您更改Person類時,您將需要更改PersonEfModel類,並使存儲庫正常工作,您將需要使用某種映射器(AutoMapper)和地圖PersonPersonEfModel,這是完全不必要的,因爲2很可能是相同的。

+0

好的,也許你是對的。但在PersonEfModel中有一些開銷。所有的ForeignKey屬性,例如我不希望他們在我的模型中。如果沒有辦法在這兩種表達類型之間進行轉換,我會接受這個答案謝謝 – 2013-03-25 14:43:31