数据库标量函数映射 - 调用导致系统.notsupportedException

发布于 2025-02-12 02:41:38 字数 2561 浏览 1 评论 0 原文

我有一个数据库应用程序,想在我的应用程序中使用标量用户定义的函数。返回值是整数。在调用中,

int pqs_id = Entities.UFN_QueryForNewPQS_ID(param_SHH_RecordingOrder, param_TillDT_UTC, param_TillDT_UTC);

我得到以下例外:

system.notsupportedException:不支持指定的方法。 在gb.ppc.entitydatamodel.entities.ufn_queryfornewpqs_id(nullable 1 shh_recordingorder,nullable 1 frofdateTime_utc,nullable'1 tilldateTime`1 tilldateTime_utc in d tilldatement_utc in d:\ project :第50行 在d:\ projects \ reporting \ source-dbaccess \ postgresql.accesstest \ program.cs中的dbaccess.program.main(string [] args)中

i在onModeLcreating()中设置一个breakpoint(),但该应用程序未通过它。

这就是我的数据库上下文实体的配置方式:

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        base.OnConfiguring(optionsBuilder);

        if (_useLoggerFactory)
        {
            optionsBuilder.EnableSensitiveDataLogging();
            optionsBuilder.UseLoggerFactory(loggerFactory);
        }

        if (DatabaseProvider == DatabaseProvider.System_Data_SqlClient)
        { 
            optionsBuilder.UseSqlServer(_connectString);
        }
        if (DatabaseProvider == DatabaseProvider.Npgsql)
        {
            optionsBuilder.UseNpgsql(_connectString);
            optionsBuilder.UseLowerCaseNamingConvention();
        }
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        //..
        modelBuilder.HasDbFunction(typeof(Entities)
                    .GetMethod(nameof(UFN_QueryForNewPQS_ID), new[] { typeof(int?), typeof(DateTime?), typeof(DateTime?) }))
                    .HasSchema("ppc")
                    .HasName("UFN_QueryForNewPQS_ID");
    }

    [DbFunction]
    public static int UFN_QueryForNewPQS_ID(int? shh_RecordingOrder, DateTime? fromDateTime_UTC, DateTime? tillDateTime_UTC) => throw new NotSupportedException();

在解决此问题时,我读了eg EF Core 2.0 中的新功能和映射您自己的标量函数,但不可解决我的问题。

我使用:

  • targetFramework:netCoreApp3.1
  • NPGSQL:版本=“ 4.1.11”
  • npgsql.entityframeworkcore.postgresql:version =“ 3.1.18”

任何帮助解决我的问题的帮助。

I have an database application and want to use a scalar user defined function in my application. The return value is integer. On invocation

int pqs_id = Entities.UFN_QueryForNewPQS_ID(param_SHH_RecordingOrder, param_TillDT_UTC, param_TillDT_UTC);

I get the following exception:

System.NotSupportedException: Specified method is not supported.
at GB.PPC.EntityDataModel.Entities.UFN_QueryForNewPQS_ID(Nullable1 shh_RecordingOrder, Nullable1 fromDateTime_UTC, Nullable`1 tillDateTime_UTC) in D:\Projects\Reporting\Source-DBAccess\PPC.EntityDataModel\Entities_Functions.cs:line 50
at DBAccess.Program.Main(String[] args) in D:\Projects\Reporting\Source-DBAccess\PostgreSQL.AccessTest\Program.cs:line 299

I set a breakpoint in OnModelCreating(), but the app didn't pass it.

This is how my database context Entities is configured:

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        base.OnConfiguring(optionsBuilder);

        if (_useLoggerFactory)
        {
            optionsBuilder.EnableSensitiveDataLogging();
            optionsBuilder.UseLoggerFactory(loggerFactory);
        }

        if (DatabaseProvider == DatabaseProvider.System_Data_SqlClient)
        { 
            optionsBuilder.UseSqlServer(_connectString);
        }
        if (DatabaseProvider == DatabaseProvider.Npgsql)
        {
            optionsBuilder.UseNpgsql(_connectString);
            optionsBuilder.UseLowerCaseNamingConvention();
        }
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        //..
        modelBuilder.HasDbFunction(typeof(Entities)
                    .GetMethod(nameof(UFN_QueryForNewPQS_ID), new[] { typeof(int?), typeof(DateTime?), typeof(DateTime?) }))
                    .HasSchema("ppc")
                    .HasName("UFN_QueryForNewPQS_ID");
    }

    [DbFunction]
    public static int UFN_QueryForNewPQS_ID(int? shh_RecordingOrder, DateTime? fromDateTime_UTC, DateTime? tillDateTime_UTC) => throw new NotSupportedException();

On solving this problem I read e.g. New features in EF Core 2.0 and Mapping your own scalar functions, but non could not solve my problem.

I use:

  • TargetFramework: netcoreapp3.1
  • Npgsql: Version="4.1.11"
  • Npgsql.EntityFrameworkCore.PostgreSQL: Version="3.1.18"

Any help to solve my problem is highly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

无所谓啦 2025-02-19 02:41:38

这是解决方案:

var statisticID = db.TPQS_ProductionQuantityStatistic
                            .Select(pqs => new
                                    {
                                        newPQS_ID = Entities.UFN_QueryForNewPQS_ID(paramIntValue, paramDateTimeValueFrom, paramDateTimeValueTill)
                                    }
                                   )
                            .FirstOrDefault();

由于标量函数始终返回一个值,因此可以在statistisid.newpqs_id中使用。

一些进一步的解释。 @Ivan-Stoev的建议使用 database.executesqlraw 不适用,因为
ufn_queryfornewpqs_id 返回一个实现的值,该值已实现为传递的参数。

上面显示的解决方案效果很好 - 任何方式。然后,我截断了实体 tpqs_productionquantquantquantstatistic ,因为我想从第一个开始就对数据库进行测试柜。我在 statisticid 上获得了 null引用异常。显然,当实体引用一个空数据库表时,未执行UDF。因此,我的最终解决方案是针对相关数据库表的实体执行UDF肯定永远不会空-e tsyp_systemparam

最终解决方案

var statisticID = db.TSYP_SystemParam
                            .Select(pqs => new
                                    {
                                        newPQS_ID = Entities.UFN_QueryForNewPQS_ID(paramIntValue, paramDateTimeValueFrom, paramDateTimeValueTill)
                                    }
                                   )
                            .FirstOrDefault();

我不知道是否有其他方法可以实现我的任务,但是这种方式有效。

This is the solution:

var statisticID = db.TPQS_ProductionQuantityStatistic
                            .Select(pqs => new
                                    {
                                        newPQS_ID = Entities.UFN_QueryForNewPQS_ID(paramIntValue, paramDateTimeValueFrom, paramDateTimeValueTill)
                                    }
                                   )
                            .FirstOrDefault();

Since the scalar function always returns a value, it is available in statisticID.newPQS_ID.

Some further explainations. The proposal of @Ivan-Stoev to use DataBase.ExecuteSqlRaw is not applicable, because
ExecuteSqlRaw returns the number of affected rows, what I can't need. The UDF UFN_QueryForNewPQS_ID returns a value which is realted to the passed parameters.

The above shown solution worked fine - in any ways. Then I truncated the entity TPQS_ProductionQuantityStatistic because I wanted to run my testcases against the database from the very first beginning. I got a null reference exception on statisticID. Apperently the UDF is not executed when the entity references an empty database table. So my final solution was to execute the UDF against a entity which related database table is for sure never empty - TSYP_SystemParam.

Final solution

var statisticID = db.TSYP_SystemParam
                            .Select(pqs => new
                                    {
                                        newPQS_ID = Entities.UFN_QueryForNewPQS_ID(paramIntValue, paramDateTimeValueFrom, paramDateTimeValueTill)
                                    }
                                   )
                            .FirstOrDefault();

I don't know if there is another way to achive my task, but this way works.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文