Existe una razón particular por la cual el expansor de LinqKit no puede recoger Expresiones de los campos?

Estoy usando LinqKit biblioteca que permite combinar expresiones sobre la marcha.

Esta es una felicidad pura para escribir la capa de acceso a datos de Entity Framewok porque varias expresiones se pueden reutilizar y combinar opcionalmente, lo que permite un código legible y eficiente.

Considere el siguiente fragmento de código:

private static readonly Expression<Func<Message, int, MessageView>> _selectMessageViewExpr =
    ( Message msg, int requestingUserId ) =>
        new MessageView
        {
            MessageID = msg.ID,
            RequestingUserID = requestingUserId,
            Body = ( msg.RootMessage == null ) ? msg.Body : msg.RootMessage.Body,
            Title = ( ( msg.RootMessage == null ) ? msg.Title : msg.RootMessage.Title ) ?? string.Empty
        };

Declaramos una expresión que proyectaMessage enMessageView (Eliminé los detalles para mayor claridad).

Ahora, el código de acceso a datos puede usar esta expresión para obtener un mensaje individual:

var query = CompiledQueryCache.Instance.GetCompiledQuery(
    "GetMessageView",
    () => CompiledQuery.Compile(
        _getMessagesExpr
            .Select( msg => _selectMessageViewExpr.Invoke( msg, userId ) ) // re-use the expression
            .FirstOrDefault( ( MessageView mv, int id ) => mv.MessageID == id )
            .Expand()
        )
    );

Esto es hermoso porque la misma expresión se puede reutilizar para obtener una lista de mensajes también:

var query = CompiledQueryCache.Instance.GetCompiledQuery(
    "GetMessageViewList",
    () => CompiledQuery.Compile(
        BuildFolderExpr( folder )
            .Select( msg => _selectMessageViewExpr.Invoke( msg, userId ) )
            .OrderBy( mv => mv.DateCreated, SortDirection.Descending )
            .Paging()
            .Expand()
        ),
    folder
    );

omo puede ver, la expresión de proyección se almacena en_selectMessageViewExpr y se utiliza para crear varias consultas diferentes.

Sin embargo, pasé mucho tiempo rastreando un extraño error dondeeste código se estrelló enExpand() llamad.
El error dijo:

No se puede emitir un objeto de tipoSystem.Linq.Expressions.FieldExpression digitarSystem.Linq.Expressions.LambdaExpression.

Solo después de un tiempo me di cuenta de queeverything funciona cuando se hace referencia a la expresión en una variable local antes de llamarseInvoke e:

var selector = _selectMessageViewExpr; // reference the field

var query = CompiledQueryCache.Instance.GetCompiledQuery(
    "GetMessageView",
    () => CompiledQuery.Compile(
        _getMessagesExpr
            .Select( msg => selector.Invoke( msg, userId ) ) // use the variable
            .FirstOrDefault( ( MessageView mv, int id ) => mv.MessageID == id )
            .Expand()
        )
    );

Est código funciona como se esperaba.

Mi pregunta es

¿Hay alguna razón específica por la cual LinqKit no reconoceInvoke en expresiones almacenadas en campos? ¿Es solo una omisión del desarrollador, o hay alguna razón importante por la cual las expresiones deben almacenarse primero en variables locales?

Esta pregunta probablemente pueda responderse mirando el código generado y verificando las fuentes de LinqKit, sin embargo, pensé que tal vez alguien relacionado con el desarrollo de LinqKit podría responder esta pregunta.

Gracias

Respuestas a la pregunta(2)

Su respuesta a la pregunta