2015-12-03 9 views
8

Ho un LINQ to Entities interrogarePosso utilizzare un CAST all'interno di una query LINQ su Entità?

From item In ctx.Items 
Select new { 
    ListPrice = item.Cost/(1M - item.Markup) 
}; 

posso specificare a EF che voglio ad applicare una cast al prezzo di listino prima interrogazione e materializzare lo ? C'è qualcosa come EntityFunctions.Cast forse? O posso usare la funzione ESQL cast?

Voglio il LINQ per generare una query SQL in questo senso

SELECT cast((Cost/(1 - Markup)) as decimal(10, 2)) AS ListPrice 

Il mio obiettivo è quello di sbarazzarsi di un mucchio di precisione/scala la query. Perché c'è sottrazione e divisione decimale, il risultato della matematica è un decimale (38, 26)! È molto più di quanto .NET possa gestire e più del necessario.

+0

Non puoi usare un membro 'Converti'? –

+0

@AmitKumarGhosh 'Convert.ToDecimal' non viene riconosciuto da EF –

+1

le uniche funzioni che conosco provengono da [SqlFunctions] (https://msdn.microsoft.com/en-us/library/system.data.objects.sqlclient.sqlfunctions % 28V = vs.110% 29.aspx). Il cast non è presente in queste funzioni. – tschmit007

risposta

2

EF consente di associare le funzioni CLR alle funzioni del database utilizzando l'attributo DbFunction. Sfortunatamente, sembra che le funzioni integrate in cast e convert non siano funzioni e non sembra possibile mapparle.

Invece è possibile creare un UDF che esegue il cast e mapparlo nello DbModel. L'API di mappatura è complicata quindi utilizzerei la libreria Code First Functions per farlo per te. (Se si utilizza prima il Database o prima il Modello, è possibile eseguire manualmente la mappatura in SSDL e CSDL). Inoltre, non c'è modo di eseguire il casting dinamico all'interno di una UDF, quindi dovrai selezionare funzioni di scrittura separate per ogni cast che vuoi. Ecco un esempio per un cast(field as decimal(10,4).

-- In SQL Server 
CREATE FUNCTION ClrRound_10_4 
(
    @value decimal(28, 10) 
) 
RETURNS decimal(10,4) 
AS 
BEGIN 
    DECLARE @converted decimal(10,4) 

    SELECT @converted = cast(round(@value, 4) as decimal(10,4)) 

    RETURN @converted 

END 
GO 
//In your DbContext class 
using CodeFirstStoreFunctions; 

public class MyContext : DbContext { 
    protected override void OnModelCreating(DbModelBuilder builder) { 
     builder.Conventions.Add(new FunctionsConvention("dbo", typeof(Udf)); 
    } 

    //etc 
} 

//In a static class named Udf (in the same namespace as your context) 
using System.Data.Entity; 

public static class Udf { 
    [DbFunction("CodeFirstDatabaseSchema", "ClrRound_10_4")] 
    public static decimal ClrRound_10_4(decimal value) { 
     throw new InvalidOperationException("Cannot call UDF directly!"); 
    } 
} 

//In your LINQ query 
from item in ctx.Items 
select new { 
    ListPrice = Udf.ClrRound_10_4(item.Cost/(1M - item.Markup)) 
}; 

Vedi questo o questo articolo MSDNblog post per ulteriori dettagli.

Problemi correlati