Rocket U2 | UniVerse & UniData

 View Only

 How to Call Universe Subroutines in EF Core 6?

Jump to Best Answer
Rudolf Kotze's profile image
Rudolf Kotze posted 10-10-2023 10:18

Introduction

I've installed the U2.EntityFrameworkCore NuGet package and successfully set up basic queries using my DbContext. Now I've hit a roadblock trying to call Universe subroutines

Problem Description

With basic CRUD operations functioning as expected using my DbContext, my next challenge is to call Universe subroutines. I can't seem to find clear documentation on how to achieve this when using the U2.EntityFrameworkCore package

What You've Tried

I've gone through the U2 Toolkit documentation, but it doesn't cover EF Core 6 specific implementations. I've also attempted to manually execute the subroutines using various EF Core methods, without any success.

Questions

  1. Has anyone successfully called Universe subroutines using the U2.EntityFrameworkCore package with EF Core 6?
  2. What is the recommended approach for calling Universe subroutines in this setup?
  3. Are there any code samples or tutorials available that cover this specific scenario?
Paul Chang's profile image
ROCKETEER Paul Chang Best Answer

I have created a sample GETCUSTOMER_STATE subroutine with one STATEID parameter. When I use the FromsqlRaw function with one parameter, it returns the correct result set.

Here is the sample code.

 SUBROUTINE GETCUSTOMER_STATE(STATEID)
$INCLUDE UNIVERSE.INCLUDE ODBC.H
SELSTMT = "SELECT * FROM CUSTOMER WHERE STATE='":STATEID:"'"
ST = SQLExecDirect(@HSTMT, SELSTMT)
RETURN

var connection_string = ConfigurationManager.ConnectionStrings["CustomerContext"].ConnectionString;

CustomerContext ctx = new CustomerContext(connection_string);

object[] paramItems = new object[]{new string("")};

paramItems[0] = "VT";

var t = ctx.Customers.FromSqlRaw("CALL GETCUSTOMER_STATE(@p0)",paramItems).ToList();

foreach (Customer item in t)

{ Console.WriteLine(item.CUSTID + "-" + item.FNAME); }

Output:

6-Betty
10-Andrew

>LIST CUSTOMER FNAME LNAME WITH STATE='VT'

CUSTOMER..    First Name..    Last Name.......

6             Betty           Burke

10            Andrew          McCaig

2 records listed.

Steve Wingfield's profile image
ROCKETEER Steve Wingfield

Hi Rudolph,

Thanks for this question, and for the very helpful phrasing!

Let me see if I can answer the three questions you posed:

1. Has anyone successfully called Universe subroutines using the U2.EntityFrameworkCore package with EF Core 6?

We have recently written a blog on this, which discusses EF Core 6.  Please see https://www.rocketsoftware.com/blogs/u2-toolkit-net-311-provider-developer-enhancements-and-improvements

2. What is the recommended approach for calling Universe subroutines in this setup?

There are a couple of ways to call subroutines from the driver.  One is in the style more typical of EF, and one is more "native" MV.  Please see the next answer for a code snippet

3. Are there any code samples or tutorials available that cover this specific scenario?

Our engineering team has provided the following code snippets illustrating the two ways:

using System.Configuration;
using U2.Data.Client.UO;
using U2.Data.Client;
using System.Data;

namespace EFCore_Delete
{

    class Program
    {
        static void Main(string[] args)
        {
            //Uci-Sample1
            try
            {
                U2ConnectionStringBuilder conn_str = new U2ConnectionStringBuilder();
                conn_str.UserID = "user";
                conn_str.Password = "password";
                conn_str.Server = "localhost";
                conn_str.Database = "HS.SALES";
                conn_str.ServerType = "UNIVERSE";
                conn_str.Pooling = false;
                string s = conn_str.ToString();
                U2Connection con = new U2Connection();
                con.ConnectionString = s;
                con.Open();
                Console.WriteLine("Connected.........................");
                U2Command command = con.CreateCommand();
                command.CommandText = "CALL *GETXMLSUB(?,?,?,?,?,?)"; // UniVerse subroutine

                command.Parameters.Clear();

                command.CommandType = CommandType.StoredProcedure;
                U2Parameter p1 = new U2Parameter();
                p1.Direction = ParameterDirection.InputOutput;

                p1.Value = "LIST CUSTOMER";
                p1.ParameterName = "@arg1";

                U2Parameter p2 = new U2Parameter();
                p2.Direction = ParameterDirection.InputOutput;
                p2.Value = "";
                p2.ParameterName = "@arg2";


                U2Parameter p3 = new U2Parameter();
                p3.Direction = ParameterDirection.InputOutput;
                p3.Value = "";
                p3.ParameterName = "@arg3";


                U2Parameter p4 = new U2Parameter();
                p4.Direction = ParameterDirection.InputOutput;
                p4.Value = "";
                p4.ParameterName = "@arg4";

                U2Parameter p5 = new U2Parameter();
                p5.Direction = ParameterDirection.InputOutput;
                p5.Value = "";
                p5.ParameterName = "@arg5";

                U2Parameter p6 = new U2Parameter();
                p6.Direction = ParameterDirection.InputOutput;
                p6.Value = "";
                p6.ParameterName = "@arg6";


                command.Parameters.Add(p1);
                command.Parameters.Add(p2);
                command.Parameters.Add(p3);
                command.Parameters.Add(p4);
                command.Parameters.Add(p5);
                command.Parameters.Add(p6);

                command.ExecuteNonQuery();

                //string s1 = command.Parameters[0].Value.ToString();//command
                //string s2 = command.Parameters[1].Value.ToString();// command option
                string s3 = command.Parameters[2].Value.ToString(); // xml
                string s4 = command.Parameters[3].Value.ToString(); //xsd
                //string s5 = command.Parameters[4].Value.ToString(); // msg #
                //string s6 = command.Parameters[5].Value.ToString(); // msg description

                Console.WriteLine("Subroutine Output:" + s3 + Environment.NewLine);
                Console.WriteLine("Subroutine Output:" + s4 + Environment.NewLine);

                con.Close();

            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);

            }
            finally
            {
                Console.WriteLine("Enter to exit: Sample1");
                string line = Console.ReadLine();
            }


            //Native-Sample2
            try
            {
                U2ConnectionStringBuilder conn_str = new U2ConnectionStringBuilder();
                conn_str.UserID = "user";
                conn_str.Password = "password";
                conn_str.Server = "localhost";
                conn_str.Database = "HS.SALES";
                conn_str.ServerType = "UNIVERSE";
                conn_str.AccessMode = "Native";   // FOR UO
                conn_str.RpcServiceType = "uvcs"; // FOR UO
                conn_str.Pooling = false;
                string s = conn_str.ToString();
                U2Connection con = new U2Connection();
                con.ConnectionString = s;
                con.Open();
                Console.WriteLine("Connected.........................");

                UniSession us1 = con.UniSession;

                string RoutineName = "!TIMDAT";
                int IntTotalAtgs = 1;
                string[] largs = new string[IntTotalAtgs];
                largs[0] = "1";
                UniDynArray tmpStr2;
                UniSubroutine sub = us1.CreateUniSubroutine(RoutineName, IntTotalAtgs);

                for (int i = 0; i < IntTotalAtgs; i++)
                {
                    sub.SetArg(i, largs[i]);
                }

                sub.Call();
                tmpStr2 = sub.GetArgDynArray(0);
                string result = "\n" + "Result is :" + tmpStr2;
                Console.WriteLine("  Response from UniSubRoutineSample :" + result);


                con.Close();

            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);

            }
            finally
            {
                Console.WriteLine("Enter to exit:Sample2");
                string line = Console.ReadLine();
            }
        }
    }
}

Rudolf Kotze's profile image
Rudolf Kotze

Hi Steve

Thanks for the reply.

I'm looking for an example to call the subroutine using EF Core and not the U2 library directly.

Rudolf Kotze's profile image
Rudolf Kotze

Thanks, Paul. This is what I was looking for.