2009-12-03 4 views
5

나는 여기서 논의 된 방법에 대해 알고 :컴파일 된 LINQ 쿼리 및 DataLoadOptions ... 트위스트!

Solving common problems with Compiled Queries in Linq to Sql for high demand ASP.NET websites

...하지만 난이 얻을으로이 내 상황에 작동하지 않습니다로드 옵션을 설정

는 "결과 후 허용되지 않습니다

가지고 쿼리에서 반환되었습니다. "

나는 엔티티와 관리자 코드를 생성하는 Codesmith PLINQO 스크립트를 사용하고, 그리고 관리자 코드는 다음과 같은 :

: 내가 처음과 같이 Searchmanager 클래스에 정적 DataLoadOptions을 삭제 시도

public partial class SearchManager 
{  
    #region Query 
    // A private class for lazy loading static compiled queries. 
    private static partial class Query 
    { 
     internal static readonly Func<MyDataContext,IOrderedQueryable<Search>> 
      GetAll = CompiledQuery.Compile(
       (MyDataContext db) => 
       from s in db.Search 
       orderby s.Name 
       select s); 
    } 
    #endregion 


    public IQueryable<Search> GetAll() 
    { 
     return Query.GetAll(Context); 
    } 
} 

public IQueryable<Search> GetAll() 
{ 
    Context.LoadOptions = MyOptions; 
    return Query.GetAll(Context); 
} 
:
public static readonly DataLoadOptions MyOptions = 
    (new Func<DataLoadOptions>(() => 
    { 
     var option = new DataLoadOptions(); 
     option.LoadWith<Search>(x => x.Rule); 
     return option; 
    }))(); 

... 다음과 같은 방법 GETALL 컨텍스트에 제공

... 그리고 그게 내가 위에서 지적한 오류를 줬어. 이것은 쿼리가 이미 컴파일되어 있으므로 "추가"DataLoadOptions를 추가 할 수 없기 때문입니까? 그렇다면 어떻게 쿼리를 컴파일하기 전에 DataLoadOptions을 적용 할 수 있습니까?

+0

체크 게시 된 답하고 실제로 오류가 쿼리를 호출하기 전에 발생하면 –

답변

0

오류 메시지 자체가 무엇이 잘못되었는지를 정확하게 알려줍니다. Linq 쿼리가 결과를 반환 한 후에는 DataLoadOptions을 적용 할 수 없습니다. 또는 이것을 말할 수있는 더 좋은 방법은 다음과 같습니다. DataLoadOptions을 적용하려면 쿼리를 실행하기 전에 수행하십시오. 나중에는 그렇게 할 수 없습니다.

+0

원하는 정보를 가지고있는 경우와 같이, 그것을 받아 수행 공개 된 IQueryable GETALL() { Context.LoadOptions을 = MyOptions; return Query.GetAll (컨텍스트); } – krisg

0

컴파일 된 쿼리에 대해서만로드 옵션을 한 번 설정할 수 있습니다. 두 번째 호출에서 오류가 발생해야합니다. 과제를 정적 생성자로 이동하면 문제가 해결됩니다.

0
public IQueryable<Search> GetAll() { 
    Context.LoadOptions = MyOptions; 
    return Query.GetAll(Context); 
} 

컨텍스트가 이미 쿼리 결과를 반환 한 경우이 할당이 너무 늦습니다. 이것은 컴파일 된 쿼리 및 DataContext의 LoadOptions 속성 할당과 관련된 모든 작업과 관련이 없습니다. 아쉽게도 LoadOptions 속성의이 동작은 msdn에 설명되어 있지 않습니다.

2

DataContext 클래스의 setter 속성에는 DataContext에 Cache에 개체가 있고 LoadOptions이 null이 아니고 설정하려고하는 LoadOptions 인스턴스가 다음과 같지 않은지 확인하는 조건이 있습니다. 이미 설정되어있는 경우 예외가 발생합니다.

대체 # 1. 각 쿼리에 대해 새 컨텍스트 만들기 (아마도 좋은 생각이 아님)
대체 # 2. 리플렉션을 사용하여 ClearCache 메서드를 호출 한 다음 새 LoadOptions를 정적으로 만들고 컨텍스트에 할당 한 다음 컴파일 된 쿼리를 가져옵니다.

public partial class SearchManager 
{  
    #region Query 
    // A private class for lazy loading static compiled queries. 
    private static partial class Query 
    { 
     internal static readonly Func<MyDataContext,IOrderedQueryable<Search>> GetAll 
     { 
      get { 
       return CompiledQuery.Compile(
        (MyDataContext db) => 
         from s in db.Search 
         orderby s.Name 
         select s); 
      } 
     } 
    #endregion 

    public IQueryable<Search> GetAll() 
    { 
     Context.ClearCache(); 
     Context.LoadOptions = MyOptions; 
     return Query.GetAll(Context); 
    } 

    public static readonly DataLoadOptions MyOptions = 
     (new Func<DataLoadOptions>(() => MakeLoadOptions<Search>(x=>x.Rule)))(); 
} 

public static class Extensions { 
    public static void ClearCache(this DataContext context) 
    { 
     const BindingFlags FLAGS = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; 
     var method = context.GetType().GetMethod("ClearCache", FLAGS); 
     method.Invoke(context, null); 
    } 

    public static DataLoadOptions MakeLoadOptions<TEntity, TResult>(this Expression<Func<TEntity,TResult>> func) { 
     DataLoadOptions options = new DataLoadOptions(); 
     options.LoadWith(func); 
     return options; 
    } 
}