Oracle Entity Framework - 调用自定义函数 (EDIT_DISTANCE)

Oracle Entity Framework - Call custom function (EDIT_DISTANCE)

我正在使用 Entity Framework 6 和 Oracle 数据库 11g(ODP.NET 管理驱动程序)。

如何在 LINQ 查询中调用 UTL_MATCH.EDIT_DISTANCE 函数?

有两种方法可以实现这一点:直接通过上下文调用 ODP.NET ADO.NET 类,或者使用 Entity Designer 中的“导入函数”对话框。

1) 下面是一些示例代码,展示了如何从 EF 代码调用 proc 而无需将它们导入到模型中——本质上,您是在提取 OracleCommand 对象。在线进行一些调查将帮助您针对实际要调用的包过程修改此设置:

var ctx = new TestContext();
var cmd = ctx.Database.Connection.CreateCommand() as OracleCommand;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "SOMESTOREDPROC";
var p_rc1 = new OracleParameter("p_rc1", OracleDbType.RefCursor, ParameterDirection.Output);
var p_rc2 = new OracleParameter("p_rc2", OracleDbType.RefCursor, ParameterDirection.Output);
cmd.Parameters.Add(p_rc1);
cmd.Parameters.Add(p_rc2);

if (ctx.Database.Connection.State != ConnectionState.Open)
    ctx.Database.Connection.Open();

var reader = cmd.ExecuteReader(); 

2)

查看 Oracle Developer Tools for Visual Studio 联机帮助中的 Entity Framework 章节。您可以使用 "Run Stored Procedure" 对话框来完成它。它会自动将元数据添加到配置文件中。

https://apexapps.oracle.com/pls/apex/f?p=44785:24:103660957753593:::24:P24_CONTENT_ID,P24_PROD_SECTION_GRP_ID,P24_PREV_PAGE:11004,,24

请参阅此处的函数导入部分。

注意:“导入函数”对话框仅使用存储过程中的第一个 REF CURSOR。按照惯例,它成为导入的实体函数的 return 值。您可能需要创建包装存储过程来进行设置。

有一个很棒的库可以帮助将数据库函数和存储过程映射到 Entity Framework。

安装 Nuget 包

- Install-Package EntityFramework.Functions

为函数创建扩展方法:

public static class OracleFunctions
{
   [Function(FunctionType.BuiltInFunction, "TO_NUMBER")]
   public static int? ToNumber(this string value) => Function.CallNotSupported<int?>();
}

将其映射到您的 EntityFramework 上下文中:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
   modelBuilder.Conventions.Add(new FunctionConvention(typeof(OracleFunctions)));
}

在 LINQ 查询中调用新映射的“ToNumber()”函数:

.FirstOrDefault(p => p.Id == "209706".ToNumber());

还有你叔叔。

不幸的是,对于驻留在不同架构中的 Oracle 函数,例如 UTL_MATCH.EDIT_DISTANCE,它将不起作用。您应该能够设置架构,但它似乎目前无法使用 Oracle 或其他东西。但是对于 SOUNDEX 等其他功能,这应该可以正常工作。

您可以阅读 Documentation for EntityFramework.Functions here

我同意 Gerrie Pretorius 的观点,如果您使用数据库优先模型,则必须向 edmx 文件添加一个函数,如下所示

   <Function Name="TO_NUMBER" Aggregate="false" BuiltIn="true" NiladicFunction="false" IsComposable="true" ParameterTypeSemantics="AllowImplicitConversion" ReturnType="number">
          <Parameter Name="valueStr" Type="varchar" Mode="In" />
        </Function>

然后将静态函数添加到 OracleFunctions class,如下所示

[EdmFunction("Model.Store", "TO_CHAR")]
public static int? ToNumber(this string value) {
    throw new NotSupportedException("this function is not supported");
}

之后就可以自由使用ToNumber函数了