9

我有一个 LINQ to Entity 查询

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

我可以向 EF 指定我希望它cast在查询和实现它之前将 a 应用于标价1吗?有没有类似的东西EntityFunctions.Cast?或者我可以使用 ESQLcast函数吗?

我希望 LINQ 沿这些行生成 SQL 查询

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

1我的目标是摆脱一堆精度/缩放查询。因为有小数的减法和除法,所以数学的结果是小数(38, 26)!这远远超出了 .NET 的处理能力,也超出了我的需要。

4

1 回答 1

2

DbFunctionEF 允许您使用该属性将 CLR 函数映射到数据库函数。不幸的是,它看起来像内置castconvert不是函数,而且看起来你不能映射到它们。

相反,您可以创建一个 UDF 进行强制转换并将其映射到DbModel. 映射 API 很复杂,所以我会使用Code First Functions库来为您完成。(如果您首先使用数据库或模型,您可以在 SSDL 和 CSDL 1中手动进行映射)。此外,没有办法在 UDF 中进行动态转换,因此您需要为所需的每个转换选择编写单独的函数。这是一个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))
};

1有关详细信息,请参阅此博客文章或此MSDN文章。

于 2015-12-03T17:42:28.787 回答