2010-07-25 2 views
4

리포지토리 계층에서 LINQ to SQL 클래스를 쿼리하고 서비스 계층에서 리포지토리 계층을 쿼리하고 컨트롤러에서 서비스 계층을 호출하도록 MVC 응용 프로그램을 연결했습니다.ASP.NET MVC - 내 서비스 계층에 데이터 캐싱을 추가하는 쉬운 방법이 있습니까?

저장소

Public Function GetRegions() As IQueryable(Of Region) Implements IRegionRepository.GetRegions 
     Dim region = (From r In dc.Regions 
       Select r) 
     Return region.AsQueryable 
    End Function 

서비스를 다음과 같이

기본적으로 나는 코드가

Public Function GetRegionById(ByVal id As Integer) As Region Implements IRegionService.GetRegionById 
     Return _RegionRepository.GetRegions() _ 
      .Where(Function(r) (r.ID = id _ 
           And r.isActive)) _ 
      .FirstOrDefault() 
    End Function 

    Public Function GetRegionByNameAndParentID(ByVal region As String, ByVal parentid As Integer) As Region Implements IRegionService.GetRegionByNameAndParentID 
     Return _RegionRepository.GetRegions() _ 
      .Where(Function(r) (r.Region = region _ 
           And r.ParentID = parentid _ 
           And r.isActive)) _ 
      .FirstOrDefault() 
    End Function 

    Public Function GetActiveRegions() As List(Of Region) Implements IRegionService.GetActiveRegions 
     Return _RegionRepository.GetRegions() _ 
      .Where(Function(r) r.isActive) _ 
      .ToList 
    End Function 

    Public Function GetAllRegions() As List(Of Region) Implements IRegionService.GetAllRegions 
     Return _RegionRepository.GetRegions().ToList 
    End Function 

나는에 캐싱을 추가 할 수있는 좋은/효율적인 방법이 있는지 궁금하네요 호출이 sa 인 경우 항상 REPO를 호출 할 필요는 없도록 서비스 계층 나를.

+0

PS : 나는이 질문을 발견했다하지만 확실히 내 질문에 대답하지 않습니다 http://stackoverflow.com/questions/102913/ 캐싱 - 데이터 객체 - 언제 - 저장소 - 서비스 패턴 - 및 - mvc –

답변

1

rockinthesixstring - 예, 익명의 기능을 사용하여 해당 레이어에 http 캐시를 추가하여 repo에서 가져 오거나 캐시에서 가져올 수 있습니다. 기본적으로, 당신은 (이 난 그냥 지금은 아음속 사용 일하고 있어요 응용 프로그램에서,하지만 당신이 계신의 전제는 동일합니다 다음 줄을 allong 할 것입니다.

/// <summary> 
    /// Returns an IQueryable based on the passed-in Expression Database 
    /// </summary> 
    IQueryable<T> IRepository<T>.Find(Expression<Func<T, bool>> expression) 
    { 
     // set up our object cacheKey 
     string keyValue = ParseExpression(expression); 

     if(keyValue==null) 
     { 
      return _repository.Find(expression); 
     } 

     string cacheKey = string.Format(EntityrootList, _className, "Find", keyValue, DateTime.UtcNow.Ticks.ToString(), string.Empty); 

     // try to populate from the cache 
     // rockinthesixstring - this is the part that is most relevant to you 
     var result = Cache.Get(cacheKey, 
           () => _repository.Find(expression), 
           CacheDuration); 

     return result; 
    } 

을 [ 컨트롤러 편집], 그렇게 같이 호출 것 (컨트롤러 _repository이 설정되어 : 예에서

readonly IRepository<Booking> _repository; 

) : 위의 예에서

[Authorize] 
[AcceptVerbs(HttpVerbs.Post)] 
public ContentResult ListBookings(int shareholderid) 
{ 
    Expression<Func<Booking, bool>> exprTree = x => x.FundShareholderEntity.ShareholderID == shareholderid; 
    var bookings = _repository.Find(exprTree).OrderByDescending(x => x.BookingDetailEntity.ActualDateFrom).OrderBy(x => x.BookingTypeID); 
    return Content(this.RenderPartialToString("BookingListNoPaging", bookings)); 
} 

, C 통증 (즉, Cache.Get())은보다 친숙한 방식으로 httpcontext 캐시를 래핑하는 클래스입니다. 이 도움이

희망 ... 짐

[편집] - 것이다 추가 캐시 인터페이스는 주사 클래스에 '논쟁':

public interface ISessionCache 
{ 
    T Get<T>(string key); 
    T Get<T>(string key, Func<T> getUncachedItem, int cacheDuration); 
    void Insert(string key, object obj, int cacheDuration, CacheDependency arg0, TimeSpan arg2); 
    void Remove(string key); 
    object this[string key] { get; } // default indexer 
    IDictionaryEnumerator GetEnumerator(); 
} 

에 추가

public class FakeCache : ISessionCache 
{... all inteface members implemented here etc..} 

또는 다음 줄을 따라 사용됩니다. HttpCache에 대한 :

public class HttpContextCache : ISessionCache 
{... all inteface members implemented here etc..} 

등 등 다시 환호 - 짐

+0

내 미안하지만 미안 귀하의 저장소 계층과 관련하여 이것을 사용하는 방법과 당신이 어떻게 컨트롤러에서 말하는에서 전화를 설명 할 수 있습니까? –

+0

위의 예제 코드에 컨트롤러 호출을 추가하겠습니다. –

+0

캐싱은 실제로 별개의 측면에 있어야합니다. 날 믿어. HttpCache에 서비스 계층을 바인드하지 않으려 고합니다. IoC 컨테이너를 사용하여 캐시하려는 메소드에 대한 캐시 인식 인터셉터를 삽입하십시오. 이렇게하면 테스트가 쉬워 질뿐 아니라 모든 서비스를 수정하지 않고도 캐시 엔진 (HttpCache, Memcached 등)을 신속하게 바꿀 수 있습니다. – Ryan

1

캐싱이 교차 절단 우려 (위키 백과에서 검색을 할), 당신이 당신의 저장소에 캐싱을 구현하는 정책 주사를 사용할 수이므로 계층이지만 Castle, Unity 등과 같은 DI 프레임 워크를 사용한다는 제약이 있습니다.이 개념의 장점은 저장소 계층에 깨끗한 코드를 유지한다는 것입니다.

나는 It Depends로 시작 하겠지만, 다른 서비스 에이전트와의 상호 작용이 필요없는 간단한 시나리오에서는 데이터베이스 액세스가 가장 느리기 때문에 데이터베이스 액세스를 캐시하는 것이 좋습니다. 그래서 서비스 계층에 대한 액세스를 캐시하지 말고 저장소 계층을 캐시하는 것이 좋습니다. Martin Fowler가 자신의 데이터 매퍼 패턴에서 설명한 바입니다.

컨트롤러와 서비스가 다른 서버에서 실행되는 분산 시나리오 인 경우 컨트롤러를 캐싱하도록 선택하여 예를 들어로드 할 때마다 참조 데이터의 직렬화를 방지 할 수 있습니다. countrylist 드롭 다운 또는 세금 코드 값.

시나리오에서는 CachingHandler를 저장소 GetRegions()에 연결하고 CacheKey를 만듭니다. 메소드와 파라미터 (존재하는 경우) 간단한 접근 방식으로 CacheKey와 결과 목록을 Hashtable (실생활에서 패턴 & 사례 캐싱 응용 프로그램 블록 또는 System.Web.Cache 사용)에 저장하고 저장소에 대한 모든 요청에 ​​캐시 키가 있는지 확인하십시오 Hashtable에서 캐시 된 목록을 반환하십시오.

구글의 빠른 검색이 시작하는 당신에게 제공합니다 http://entlib.codeplex.com/Thread/View.aspx?ThreadId=34190

관련 문제