2009-12-03 10 views
5

que sé sobre el método discutido aquí:Compiled LINQ query & DataLoadOptions ... ¡con un giro!

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

... pero esto no funciona para mi situación como llegue a:

"Configuración de las opciones de carga no está permitido después de los resultados tienen sido devuelto de una consulta ".

estoy usando guiones CodeSmith PLINQO para generar entidades y código del gestor y el código del gestor ve algo como esto:

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); 
    } 
} 

primero intenté dejar caer DataLoadOptions estáticos en la clase Searchmanager así:

public static readonly DataLoadOptions MyOptions = 
    (new Func<DataLoadOptions>(() => 
    { 
     var option = new DataLoadOptions(); 
     option.LoadWith<Search>(x => x.Rule); 
     return option; 
    }))(); 

... entonces proporcionar al contexto en el método GetAll como:

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

... y eso me dio el error que anoté anteriormente. ¿Esto se debe a que la consulta ya está compilada y, por lo tanto, no puede agregarse DataLoadOptions "adicionales"? De ser así, ¿cómo sería posible aplicar DataLoadOptions antes de la consulta que se está compilando?

+0

verificación de la respuesta publicado y hacer aceptarlo si recibiera la información que desee –

Respuesta

0

El mensaje de error en sí mismo le dice exactamente lo que está mal. No puede aplicar DataLoadOptions después de que una consulta Linq haya arrojado resultados. O tal vez una mejor manera de decir esto es la siguiente. Si desea aplicar DataLoadOptions, hágalo antes de ejecutar la consulta. No puedes hacerlo después.

+0

En realidad se produce el error antes de la consulta se llama, como se muestra: pública IQueryable GetAll() { Context.LoadOptions = MyOptions; return Query.GetAll (Contexto); } – krisg

0

Solo puede establecer las opciones de carga una vez para una consulta compilada. El error debe ser lanzado en la segunda llamada. Mueva la asignación a un constructor estático y eso debería resolver su problema.

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

Esta asignación es demasiado tarde, si el contexto ya ha devuelto los resultados de la consulta. Esto no tiene nada que ver con las consultas compiladas y todo tiene que ver con la asignación de la propiedad LoadOptions de DataContext. Desafortunadamente, este comportamiento de la propiedad LoadOptions no está documentado en msdn.

2

En la propiedad setter de la clase DataContext, hay una condición que comprueba si DataContext tiene algún objeto en su caché, y LoadOptions NO es nulo, y la instancia de LoadOptions que está intentando establecer no es la misma que el que ya está configurado, entonces obtienes esa excepción.

Alternativa n. ° 1. Cree un nuevo contexto para cada consulta (probablemente no sea una buena idea)
Alternativa n. ° 2. Llame al método ClearCache utilizando la reflexión, luego cree una nueva LoadOptions de forma estática, asígnela al contexto, y finalmente, obtenga la consulta compilada.

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; 
    } 
}