首页 > 解决方案 > 如果参数可能为空,则从 sql 选择中获取值

问题描述

在使用 EF Core 的 ASP.NET MVC Core 应用程序中的任意 sql 查询中寻找一种方法来获取第一列中第一行的值。

   var total = ctx.ExecuteScalar<decimal?>(@"select ... where p1={0}", null);

使用 Npgsql EF Provider尝试了来自https://github.com/dotnet/EntityFramework.Docs/issues/969的https://github.com/weitzhandler代码 (更改为同步):

public partial class EevaContext : DbContext
{   
    public T ExecuteScalar<T>(string rawSql, params object[] parameters)
    {  
        var context = this;
        var conn = context.Database.GetDbConnection();
        using var command = conn.CreateCommand();
        command.CommandText = rawSql;
        if (parameters != null)
            foreach (var p in parameters)
                command.Parameters.Add(p ?? DbNull.Value);
        conn.Open();
        return (T)command.ExecuteScalar();
    }

如果参数值为空行

command.Parameters.Add(p ?? DbNull.Value);

抛出错误

InvalidCastException:值“”不是“NpgsqlParameter”类型,不能在此参数集合中使用。Npgsql.NpgsqlParameterCollection.Cast(对象值)

哪个是运行此类查询的最佳方式?也许 EF 核心有一些内置方法?还是使用某种类型并将其注入 EF Context is OnModelCreated 方法是否更好?

如果没有更好的方法如何修复此代码以便也接受具有空值的参数?

有很多这样的查询在应用程序中有很多参数,并且在大量工作中重新编写所有这些查询。WebMatrix QueryValue 在 .NET 4 中使用,它允许在参数中使用空值。

标签: entity-frameworkentity-framework-coreado.netnpgsqlexecutescalar

解决方案


command.Parameters.Add(p ?? DbNull.Value);

pNpgsqlParameter,还是您要发送的某个值?您不能简单地将值(或 null)添加到command.Parameters.Add- 您需要使用 NpgsqlParameter 包装这些值或command.Parameters.AddWithValue()改用它们。请注意,NpgsqlParameter 还需要ParameterName正确设置,对应于原始 SQL 中的占位符(例如@param1)。


推荐阅读