EF: usando campos no mapeados en consultas

Tengo un vicio confesable (creo) en programación: las enumeraciones. Siempre que puedo, las uso. Cuando, aprovechando unas semanas de verano con poca carga de trabajo, intenté mapear parte de la base de datos de SAP Business One con Entity Framework (lo que tuvo su complicación, que no es lo que se dice muy relacional), me pregunté si podía utilizar enumeraciones para los campos de estado de documentos, que tan pronto pueden ser O/C como P/R/L/C o cualquier otra forma super-intuitiva.

No me refiero sólo a tener una propiedad de sólo lectura no mapeada para obtener un valor comprensible con los datos ya cargados, o sea, esto:

    <Column("Status")>
    Public Property EstadoSAP As String
    <NotMapped>
    Public ReadOnly Property EstadoEnumerado As EWORSAPStatus
        Get
            Return Convierteme(Me.EstadoSAP)
        End Get
    End Property

Lo que buscaba era poder hacer consultas directamente con el campo enumerado. Una búsqueda por Internet me llevó a descubrir Linq.Tranlations.

Básicamente, la teoría es que debo indicarle el traductor en el Get de la propiedad no mapeada:

    <Column("Status")>
    Public Property EstadoSAP As String
    ''' <summary>
    ''' Conversión de <see cref=EstadoSAP"/> a valor enumerado. Usar con Translations."
    ''' </summary>
    ''' <returns></returns>
    <NotMapped>
    <Display(Name:="Estado", Description:="Estado del documento")>
    Public Property EstadoDocumento As EWORSAPStatus 
        Get
            Return EstadoDocumentoExpression.Evaluate(Me)
        End Get
    (...)
    

Y creamos ese traductor:

    Private Shared ReadOnly EstadoDocumentoExpression As CompiledExpression(Of OrdenFabricacionCabecera, EWORSAPStatus) =
                DefaultTranslationOf(Of OrdenFabricacionCabecera) _
                .[Property](Function(e) e.EstadoDocumento) _
                .[Is](Function(e) If(e.EstadoSAP = Constantes.WOR_ESTADO_PLANIFICADA,
                                     EWORSAPStatus.Planificada,
                                     (If(e.EstadoSAP = Constantes.WOR_ESTADO_LIBERADA,
                                        EWORSAPStatus.Liberada,
                                        If(e.EstadoSAP = Constantes.WOR_ESTADO_CANCELADA,
                                            EWORSAPStatus.Cancelada, EWORSAPStatus.Cerrada)))))

Los herramientas que podemos usar para la traducción son las mismas que tenemos en EF, si no me equivoco. La colección de If de arriba no está por gusto: de ahí se tiene que montar la consulta a la BDD. Para usarlo, como dice el autor, hay que añadir a nuestra consulta Linq el término WithTranslatios para que sepa que estamos en el reto de la super pregunta:

Dim oOrdenes = oContext.OrdenesFabricacion.Where(Function(x) x.EstadoEnumerado = EWORSAPStatus.Planificada).WithTranslations

En fin, una pequeña utilidad que me hace la vida más fácil.

Nos vemos en el Forlon.

Deja un comentario