通过实体框架调用存储过程后,类型转换无效

时间:2019-03-27 17:17:46

标签: c# oracle entity-framework linq

我已经在Oracle 12.2中创建了以下存储过程:

create or replace PROCEDURE "SP_VARIABELEN_HIERARCHY" (
PP_USER_IN      IN  VARCHAR2,
    PCPID_IN        IN  VARCHAR2,
    VAR_CODE_IN     IN  VARCHAR2,
    FASE_NR_IN      IN  NUMBER,
    P_RESULTS       OUT SYS_REFCURSOR
    ) IS
    BEGIN

OPEN P_RESULTS FOR
    SELECT  DISTINCT        LEVEL
                            VAR_CODE,
                            FASE_NR,
                            GENSTAT_VOLG_NR
    FROM                    EP3_VARIABELEN_FS2_HULP
    WHERE PP_USER           = PP_USER_IN
    AND CODE                = PCPID_IN
    CONNECT BY PRIOR AFG    = VAR
    AND PP_USER             = PP_USER_IN
    AND CODE                = PCPID_IN
    START WITH VAR_CODE     = VAR_CODE_IN
    AND FASE_NR             = FASE_NR_IN
    AND PP_USER             = PP_USER_IN
    AND CODE                = PCPID_IN
    ORDER BY LEVEL DESC, GENSTAT_VOLG_NR;
    END SP_VARIABELEN_HIERARCHY;

我已经在App.config中配置了存储过程,如下所示:

  <oracle.manageddataaccess.client>
    <version number="*">
      <implicitRefCursor>
        <storedProcedure schema="EPROS" name="SP_VARIABELEN_HIERARCHY">
          <refCursor name="P_RESULTS">
            <bindInfo mode="Output" />
            <metadata columnOrdinal="0" columnName="VAR_CODE" providerType="Varchar2" dataType="System.String" allowDBNull="true" nativeDataType="Varchar2" columnSize="10" />
            <metadata columnOrdinal="1" columnName="FASE_NR" providerType="Int64" dataType="System.Int64" allowDBNull="true" nativeDataType="Number" columnSize="12" />
            <metadata columnOrdinal="2" columnName="GENSTAT_VOLG_NR" providerType="Int64" dataType="System.Int64" allowDBNull="true" nativeDataType="Number" columnSize="12" />
          </refCursor>
        </storedProcedure>

我已将SP导入到Entity Framework中,并创建了一个具有复杂类型的导入功能,该功能是根据App.config中的数据生成的。

我编写了以下单元测试:

using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Wur.Epros.Core.Infrastructure;
using Wur.Epros.Core.Repositories;
using Wur.Epros.Core.Tests.Base;

namespace Wur.Epros.Core.Tests.Repositories
{
    [TestClass]
    public class Ep3VariabelenFs2HulpRepositoryTests : TestBase
    {
        [TestMethod]
        public void RekenregelsTest()
        {
            using (var dbContext = EprosEntities)
            {
                dbContext.Database.BeginTransaction();
                string cUSER = "VISSCHER";
                string cPCPID = "D0600513_1072";
                string cVAR_CODE = "DOPJ2";
                int cFASE_NR = 2;


                string sSQL = string.Empty;
                //var result = Ep3VariabelenFs2HulpRepository.Instance.Get(v =>
                //    v.PP_USER == cUSER
                //    && cPCPID == cPCPID
                //    && )
                sSQL = "SELECT DISTINCT LEVEL";
                sSQL = sSQL + " , VAR_CODE";
                sSQL = sSQL + " , FASE_NR";
                sSQL = sSQL + " , GENSTAT_VOLG_NR";
                sSQL = sSQL + " FROM EP3_VARIABELEN_FS2_HULP";
                sSQL = sSQL + " WHERE PP_USER        = '" + cUSER + "'";
                sSQL = sSQL + " AND CODE             = '" + cPCPID + "'";
                sSQL = sSQL + " CONNECT BY PRIOR AFG =      VAR ";
                sSQL = sSQL + " AND PP_USER          = '" + cUSER + "'";
                sSQL = sSQL + " AND CODE             = '" + cPCPID + "'";
                sSQL = sSQL + " START WITH VAR_CODE  = '" + cVAR_CODE + "'";
                sSQL = sSQL + " AND FASE_NR          =  " + cFASE_NR;
                sSQL = sSQL + " AND PP_USER          = '" + cUSER + "'";
                sSQL = sSQL + " AND CODE             = '" + cPCPID + "'";
                sSQL = sSQL + " ORDER BY LEVEL DESC";
                sSQL = sSQL + "        , GENSTAT_VOLG_NR";

                var result1 = GetDataTable(dbContext, sSQL);

                var result2 = Ep3VariabelenFs2HulpRepository.Instance.GetEp3VariabelenHierarchy(cUSER, cPCPID, cVAR_CODE, cFASE_NR);

                var count1 = result1.Rows.Count;
                var count2 = result2.Count();

                Assert.AreEqual(count1, count2, "Count");
            }
        }
    }
}

Table description

我们正在使用Entity Framework从使用SQL字符串转换为LINQ。

现在,每次执行单元测试时,我都会收到InvalidCaseException。我的猜测是配置不正确,但我无法动手。

实体框架版本:6 Oracle版本12.2

1 个答案:

答案 0 :(得分:0)

在这里愚弄了我自己。仔细查看顶部的存储过程。 LEVEL和VAR_CODE之间的逗号缺失,导致VAR_CODE成为LEVEL的别名。

我不明白为什么会抛出InvalidCastException。我在App.config中为复杂类型遗漏了LEVEL,因此它无论如何应该起作用(给出错误的结果)。很奇怪。

编辑:

回想起来,我确实知道出了什么问题。 LEVEL字段是NUMBER,VAR_CODE是VARCHAR2。因此,别名VAR_CODE会在预期会出现VARCHAR2的地方提供一个NUMBER,因此会出现InvalidCastException。