Funciones personalizadas en expresiones LINQ

En las últimas versiones de Entity Framework ciertos métodos que antes si eran aceptados, como también se podía realizar en SQL, han dejado de estar disponibles. Aquellas funciones heredadas directamente de SQL han quedado englobadas en la misma clase. Algo que antes era habitual pero no precisamente una buena forma de solucionar... las conversiones de tipos de datos, ¿quien no ha convertido un string en entero en SQL?

LINQ to Entities does not recognize the method 'XXXXXXX' method, and this method cannot be translated into a store expression

Si hablamos con propiedad y utilizando todo el potencial de los ORM no es una buena práctica, debemos revisar y guardar los datos con el tipo más apropiado, pero si nos vemos forzados a utilizarlas... podemos personalizar funciones dentro de nuestro modelo de datos.

Abrimos nuestro EDMX y definimos la función:

    <edmx:ConceptualModels>
      <Schema Namespace="NombreDeMiModelo" Alias="Self" annotation:UseStrongSpatialTypes="false" xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" xmlns:customannotation="http://schemas.microsoft.com/ado/2013/11/edm/customannotation" xmlns="http://schemas.microsoft.com/ado/2009/11/edm">
        <Function Name="convertirDouble" ReturnType="Edm.Double"> 
        <Parameter Name="stringvalue" Type="Edm.String" /> 
        <DefiningExpression> 
            cast(stringvalue as Edm.Double)
        </DefiningExpression> 
        </Function>
...       

Definimos en nuestra clase la función:

using System;
using System.Data.Entity;
using System.Data.Objects.DataClasses;

public partial class MiModeloContext
{
    /// <summary>
    ///     Este método existe para poder ser usando dentro de expresiones LINQ
    ///     convierte un texto en número (Double)
    /// </summary>

    [DbFunction("NombreDeMiModelo", "convertirDouble")]
    public static double convertirDouble(string stringvalue)
    {
        return Double.Parse(stringvalue);
    }
}

 Ya podemos utilizar la función dentro de las expresiones:

datos = miEntidad.miDato.Where(x => SqlFunctions.IsNumeric(x.aux) > 0 &&
MiModeloContext.ParseDouble(x.aux) > numero)
.FirstOrDefault();

 

Aunque deberemos revisar si realmente nuestro modelo de datos es coherente...

Referencia: Calling Functions in LINQ to Entities Queries


Agregar comentario

Loading