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" 对话框来完成它。它会自动将元数据添加到配置文件中。
请参阅此处的函数导入部分。
注意:“导入函数”对话框仅使用存储过程中的第一个 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
等其他功能,这应该可以正常工作。
我同意 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函数了
我正在使用 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" 对话框来完成它。它会自动将元数据添加到配置文件中。
请参阅此处的函数导入部分。
注意:“导入函数”对话框仅使用存储过程中的第一个 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
等其他功能,这应该可以正常工作。
我同意 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函数了