2013-10-29 61 views
0

我正在使用實體框架6,並且已經實現了一些存儲庫模式的相似之處。最初,我的存儲庫具有像GetAll這樣的函數,它返回IEnumerable以避免數據層抽象泄漏太多。但是,我的服務層(它是我的存儲庫的包裝幷包含業務邏輯)需要對查詢進行更多的控制。控制,例如相關實體的急切加載,僅選擇某些列等。因此,爲了避免將DbContext暴露給我的服務層,我調整了存儲庫,以便它們現在返回IQueryable,以便服務層可以執行諸如鏈Include s到查詢等IQueryable功能,如包含,但對於單個實體?

問題是我的存儲庫有一個返回單個實體的方法,該函數只是返回該實體的POCO。這些是需要急切加載的最可能的功能,請致電Include。顯然,無法從POCO那裏做到這一點。

有沒有像IQueryable爲單個實體額外鏈接Include邏輯等?或者調整這種邏輯以適應這種情況?我的一個倉庫的一個例子是這樣的:

namespace Portal.Repositories 
{ 
    public class UploadRepository : IUploadRepository 
    { 
     private readonly IPortalContext m_context; 

     public UploadRepository(IPortalContext context) 
     { 
      m_context = context; 
     } 

     #region Methods 

     public int Count(Expression<Func<Upload, bool>> predicate) 
     { 
      return m_context.Uploads.Count(predicate); 
     } 

     public Upload Get(Expression<Func<Upload, bool>> predicate) 
     { 
      return m_context.Uploads.FirstOrDefault(predicate); 
     } 

     public Upload Insert(Upload entity) 
     { 
      return m_context.Uploads.Add(entity); 
     } 

     public Upload Delete(Upload entity) 
     { 
      return m_context.Uploads.Remove(entity); 
     } 

     public IQueryable<Upload> All() 
     { 
      return m_context.Uploads; 
     } 

     public IQueryable<Upload> Where(Expression<Func<Upload, bool>> predicate) 
     { 
      return m_context.Uploads.Where(predicate); 
     } 

     #endregion 
    } 
} 

你可以看到我Get方法,以及如何是不可能爲我服務,挑選時Include或不給,因爲它只是返回一個POCO。

+0

我想我可以刪除'GET'庫方法一起,並迫使我的服務使用'All'或'Where',並調用'FirstOrDefault'自己。 – Ryan

回答

1

您可以在存儲庫中添加一些功能來傳遞一些包含表達式。

using System.Data.Entity; 

namespace Portal.Repositories 
{ 
    public class UploadRepository : IUploadRepository 
    { 
    public Upload Get(
     Expression<Func<Upload, bool>> predicate, 
     params Expression<Func<Upload, object>>[] includeExpressions) 
    { 
     var uploads = m_context.Uploads; 
     foreach (var i in includeExpressions) 
     uploads = uploads.Include(i); 
     return uploads.FirstOrDefault(predicate); 
    } 
    } 
} 
+0

有趣。我喜歡這個。我會試試看! – Ryan

1

如何:

public List<TEntity> Get(Expression<Func<TEntity, bool>> filter = null, 
         Func<IQueryable<TEntity>, IOrderedEnumerable<TEntity>> orderBy = null, 
            string includeProperties = "") 
    { 
     IQueryable<TEntity> query = DbSet; 
     if (filter != null) 
     { 
      query = query.Where(filter); 
     } 

     query = includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Aggregate(query, (current, includeProperty) => current.Include(includeProperty)); 

     if (orderBy != null) 
     { 
      return orderBy(query).ToList(); 
     } 
     else 
     { 
      return query.ToList(); 
     } 
    } 

[編輯]:這是我目前正在使用自己的代碼是什麼。您需要更改和調整代碼以符合您的目的,但想法是將Include屬性作爲逗號分隔值傳遞給您的Get函數。