Oracle Entity Framework - Call custom function (EDIT_DISTANCE)

妖精的绣舞 提交于 2019-12-30 09:31:56

问题


I am using Entity Framework 6 and Oracle Database 11g (ODP.NET Manage Driver).

How to call UTL_MATCH.EDIT_DISTANCE function in LINQ query?


回答1:


There is an awesome Library to help with mapping Database functions and Stored Procedures to Entity Framework.

Install the Nuget package

- Install-Package EntityFramework.Functions

Create Extension Methods for functions:

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

Map it on your EntityFramework Context:

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

Call your newly mapped "ToNumber()" function in your LINQ queries:

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

And bobs your Uncle.

Unfortunately, for Oracle functions that resides in a different schema, like UTL_MATCH.EDIT_DISTANCE it will not work. You are supposed to be able to set the schema, but it seems like it is not currently working with Oracle or something. But for other fucntions like SOUNDEX etc. this should work fine.

You can read the Documentation for EntityFramework.Functions here




回答2:


There are two ways to achieve this: Call ODP.NET ADO.NET classes directly via a context, or use the Import Function dialog in Entity Designer.

1) Here's some example code showing how you can call procs from EF code without importing them into your model - essentially you are pulling out the OracleCommand object. A little investigation online will help you modify this for the package procedure you actually want to call:

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)

Have a look at the Entity Framework chapter in the Oracle Developer Tools for Visual Studio online help. You use the "Run Stored Procedure" Dialog to do it. It adds the metadata to the config file automatically.

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

See the function import section there.

Note: Only the first REF CURSOR in a stored procedure is used by the Import Function dialog. It becomes the return value of the imported Entity Function by convention. You may need to create a wrapper stored procedure to set this up.




回答3:


I agree with Gerrie Pretorius and if you used database first model , you must add a function to edmx file like below

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

Then add a static function to OracleFunctions class like below

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

After that you can use ToNumber function freely.



来源:https://stackoverflow.com/questions/32271718/oracle-entity-framework-call-custom-function-edit-distance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!