EFCore使用数据库函数

前言

有些数据库的函数在.Net中有对应的函数映射,但是其中一些是没有的,这样子做是为了保持实体框架API在不同的数据库提供程序之间保持一致。

但是你可以编写代码来补充,通过注册函数,可以在EFCore中来使用数据库的函数。

内置函数

支持通过修改数据库上下文来增加对数据库内置函数的调用, 举例以使用pgsql的内置函数to_char为例,我们有一个数据库上下文OpenDbContext,修改增加如下方法

请注意,我们没有实现方法,我们只是提供了正确的签名

/// <summary>
/// pg to_char内置函数
/// </summary>
/// <param name="input">要转换的值</param>
/// <param name="format">转换的格式</param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
[DbFunction(Name = "to_char", IsBuiltIn = true, IsNullable = false)]
public static string ToChar(DateTime input, string format = "yyyy-MM-dd HH24:mi:ss")
{
    throw new NotImplementedException();
}

IsBuiltIn指是否为内置函数 IsNullable指是否可以为null

然后我一个简单的查询操作

[HttpGet("time/tochar")]
public async Task<string> TimeToChar()
{
    var list = await _openDbContext.Users
        .Select(t => OpenDbContext.ToChar(t.CreateTime, "yyyy-MM-dd HH24:mi:ss"))
        .ToListAsync();

    return "success";
}

执行查询的时候,会生成以下SQL语句

SELECT to_char(u.create_time, 'yyyy-MM-dd HH24:mi:ss')
FROM sample."user" AS u

自定义函数

除了可以使用内置函数以外,还可以创建自己的sql函数并且以这种方式进行添加,下面使用pgsql创建一个简单的数据库函数

CREATE OR REPLACE FUNCTION sample.add_credit(source_credit double precision, addCredit int4)
    RETURNS double precision AS
$$
SELECT source_credit + addCredit;
$$
LANGUAGE SQL;

现在还在数据库上下文中注册

/// <summary>
/// 添加学分的自定义函数
/// </summary>
/// <param name="sourceCredit">原始学分</param>
/// <param name="addCredit">要添加的学分</param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
[DbFunction(Name = "add_credit", Schema = "sample", IsBuiltIn = false)]
public static double AddCredit(double sourceCredit, int addCredit)
{
    throw new NotImplementedException();
}

然后我编写一个简单的查询操作

/// <summary>
/// 学分相加
/// </summary>
/// <returns></returns>
[HttpGet("double/tochar")]
public async Task<string> DoubleAdd()
{
    var list = await _openDbContext.Users
        .Select(t => OpenDbContext.AddCredit(t.Credit, 10))
        .ToListAsync();

    return "success";
}

执行查询的时候,会生成以下SQL语句

SELECT sample.add_credit(u.credit, 10)
FROM sample."user" AS u

总结

使用 DbFunctions 是一种在EFCore查询中利用特定数据库功能的有用方法,但是需要注意。因为您正在使用数据库特定的功能,所以如果您想这样做,后期考虑移植到其他数据库就会变得更加困难。

参考文档

docs:https://docs.microsoft.com/zh-cn/ef/core/querying/database-functions

数据库函数:https://timdeschryver.dev/blog/consuming-sql-functions-with-entity-framework

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值