2014-10-29 17 views
0

我使用EF6在當前web api項目中實現存儲庫模式。目前,我有以下功能(在CustomerRepository)返回一個客戶:通用資源庫中的SingleOrDefault?

public override Customer Get(int id, params Expression<Func<Customer , object>>[] include) 
    { 
     if (include.Any()) 
     { 
      var set = include.Aggregate<Expression<Func<Customer , object>>, IQueryable<Customer >> 
         (dbset, (current, expression) => current.Include(expression)); 

      return dbset.SingleOrDefault(x => x.Id == id) 
     } 

     return dbset.Find(id); 
    } 

這工作得很好,但我想移動的上述方法在我的通用存儲庫。這裏的問題是SingleOrDefault,因爲Id不會被稱爲T.

有沒有辦法解決這個問題?我需要實現一個接口嗎?

作爲一個方面,我的所有實體的第一個屬性是'int Id'。

+0

你可以把你的存儲庫代碼?我認爲你可以這樣做:(public class Repository where T:IKey),IKey是一個包含Id屬性的接口 – Monah 2014-10-29 08:00:34

回答

0

這工作得很好,

嗯,你能肯定:

return dbset.SingleOrDefault(x => x.Id = id) 

不是這應該是:

return dbset.SingleOrDefault(x => x.Id == id) 

無論如何,如果你所有的實體有一個整數Id屬性,爲什麼不讓他們全部實現一個接口:

public interface IEntity 
{ 
    int Id { get; } 
} 

然後你將約束你的泛型T參數到基本倉庫中的這個接口,你將知道如何編寫lambda。

+0

我使用Database First。我是否需要爲EF從模型創建的每個實體創建部分類? – 2014-10-29 07:59:54

+0

不,只需創建一個僅包含Id的IKey接口,讓所有類實現此接口(它不會更改您的模型或創建數據庫) – Monah 2014-10-29 08:02:42

+0

EF設計器中的哪個位置可以設置接口?看起來我必須爲每個實體創建一個部分類。 – 2014-10-29 08:06:35

1

EF6有一個Find()方法,這種方法做你所需要的。

http://msdn.microsoft.com/en-us/library/gg696418(v=vs.113).aspx

public T Get(int id) 
{ 
    return dbset.Find(id); 
} 

不要擔心它加載更多連接的表(包括)超過需要。這對於單個記錄來說並不是什麼大事。編輯:對不起,Find實際上並沒有做任何急切的加載。相關實體只有在已經被上下文跟蹤的情況下才會被返回。