2008-11-05 2 views
6

linq 쿼리가 있고이를 분산 캐싱 (Velocity)에 대한 직렬화 가능 개체에 넣으려고하지만 LINQ-to-SQL 그래서LINQ-SQL-SQL 지연 목록을 serialize하는 방법

return from b in _datacontext.MemberBlogs 
        let cats = GetBlogCategories(b.MemberBlogID) 
        select new MemberBlogs 
        { 
         MemberBlogID = b.MemberBlogID, 
         MemberID = b.MemberID, 
         BlogTitle = b.BlogTitle, 
         BlogURL = b.BlogURL, 
         BlogUsername = b.BlogUsername, 
         BlogPassword = b.BlogPassword, 
         Categories = new LazyList<MemberBlogCategories>(cats) 
        }; 

LazyList이다 롭 Conery 그의 MVC의 점포에서 사용하는 것과 동일한 클래스 ...

세 가지 클래스

가 직렬화 표시됩니다 (MemberBlogs, MemberBlogCategories, LazyList ... 어떤처럼 게으른 목록

아이디어?

답변

6

분산 캐시에 넣으려면 LazyList를 모두 피해야합니다. 당신은 다음과 같이 전체 LINQ 문 주위 .ToList()를 호출 할 수 있습니다 : 그것은 평가 될 수있는 쿼리가 강제로하기 때문에

(from x select new MemberBlogs).ToList() 

이 다음 캐시 할 수 있어야합니다.

2

캐싱하는 경우 왜 게으른 목록을 사용하고 있습니까? 게으른 목록을 사용하지 않고 캐싱을 사용하면 문제가 해결됩니다.

3

저는 추측하고 있지만 문제는 결과 대신 쿼리를 직렬화한다는 것입니다. LazyList의 구현이 어떻게되는지는 모르겠지만 직렬화하기 전에 실제로 쿼리를 실행하는 OnSerializing 메서드를 추가 할 수 있습니다. 뭔가 같은 :

[OnSerializing] 
private void ExecuteLinqQuery(StreamingContext context) 
{ 
    if (!SomethingThatIndicatesThisLinqQueryHasNotBeenExecuted) 
     LinqVariable.ToList() 
} 

이 당신이 (당신의 캐시로 이동하지 않습니다 아무것도) 게으른로드를 계속받을 방법이 있지만,이 캐시 히트 않는 경우에도, 그것은 LINQ 쿼리를 실행할 수 있습니다 및 결과를 캐시하십시오.

0

나는 이것이 오래된 게시물이지만, LazyList를 실행하여 AppFabric Cache에 넣고 싶었던 것과 동일한 문제가 있음을 알고 있습니다. LazyList 유형에 사용자 지정 직렬화 논리를 추가했습니다.

첫 번째 부분은 이제 다음과 같습니다

public class LazyList<T> : IList<T>, ISerializable 
{ 

    public LazyList() 
    { 
     this.query = new List<T>().AsQueryable(); 
    } 

    public LazyList(SerializationInfo info, StreamingContext context) 
    { 
     try { 
      this.inner = (List<T>)info.GetValue("InnerList", typeof(List<T>)); 
     } 
     catch (Exception ex) 
     { 
      this.inner = null; 
     } 
    } 

    public void GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     if (this.inner != null) 
      info.AddValue("InnerList", this.inner.ToList()); 
    } 

    public LazyList(IQueryable<T> query) 
    { 
     this.query = query; 
    } 

    public LazyList(List<T> l) 
    { 
     inner = l; 
    } 
}