如何在Entity Framework Core中调用标量函数

15

根据这篇文章,我试图使用Entity Framework Core将内部SQL函数调用到我的应用程序中。

我像这样在上下文中创建了静态方法:

public class DbContext : DbContext
{
    public DbContext(DbContextOptions<DbContext> options) : base(options)
    {
    }

    [DbFunction("FN_ENCRYPT", "DBO")]
    public static string FN_ENCRYPT(string ENC)
    {
        throw new NotImplementedException();
    }
}

在这之后,我对如何调用它有点困惑,所以我试着用这种方式(因为它是静态方法):

public string Encript(string word)
{
    return DbContext.FN_ENCRYPT(word);
}

但是,猜猜发生了什么?我收到了一个“好玩”的NotImplementedException :)

有人能帮助我吗?
提前感谢。
2个回答

18

使用该调用本身抛出异常,因为它实际上执行了C#代码。之所以建议抛出异常,正是为了避免意外使用,即通过直接调用它。这个签名将由给定的 LINQ 提供程序解释,并转换为适当的 SQL 语句。

在 MS 的EF Core 数据库标量函数映射中:

它们可以用于 LINQ 查询并翻译为 SQL

以下是一个工作演示:

模型和 DbContext

public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime DOB  { get; set; }
}

public class MyDbContext:DbContext
{
    public MyDbContext(DbContextOptions<MyDbContext> options):base(options)
    { }

    public DbSet<Employee> Employees { get; set; }

    [DbFunction("CalculateAge", "dbo")]
    public static int CalculateAge(DateTime dob)
    {
        throw new NotImplementedException();
    }
}

以及使用

public IActionResult GetAge(int employeeId)
    {
        var query = _context.Employees
                .Where(x => x.Id == employeeId)
                .Select(d =>new
                { 
                    Name=d.Name,
                    DOB=d.DOB,
                    Age= MyDbContext.CalculateAge(d.DOB)
                }).ToList();
        return Json(query);
    }

结果

输入图像描述


5
是的,它是这样工作的,但我仍然有些困惑,因为在DbContext中你只是使用Employees类来调用DbFunction。在我的情况下,没有任何表格与该函数相关联。需要调用表格并不合理(我尝试了数据库中的每个表格,代码仍然可以正常运行)。 - Guilherme Golfetto
找不到列“dbo”或用户定义的函数或聚合…… - phil123456
在我的情况下,它总是抛出 throw new NotImplementedException(); - Pallavi Kulkarni - Dhepe
请查看我对类似问题的回答,了解如何直接调用它:https://dev59.com/RbHma4cB1Zd3GeqPRM5l#68902584 - Extragorey

1

虽然没有选项可以调用与EF中现有实体无关的标量函数,但仍然可以使用现有的EF的DB上下文以这种方式完成:

using (DbCommand command = this.storageContext.Database.GetDbConnection().CreateCommand())
{
    command.CommandText = "SELECT dbo.YourFunc()";
    await this.storageContext.Database.OpenConnectionAsync();

    bool result = (bool)(await command.ExecuteScalarAsync());

    await this.storageContext.Database.CloseConnectionAsync();
    return result;
}

这个返回 bool


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接