Npgsql 3.1.0-alpha5不允许将null传递给函数

时间:2015-11-24 13:59:49

标签: npgsql

我一直在使用beta Npgsql库(3.1.0-alpha5)在linux上试验coreclr。将参数传递给函数时,只要TIMESTAMP参数为null,库就会抛出错误:“参数< blah>必须设置”。以下是测试用例。

create sequence sq_category_id start 1 increment 1;

create table category (
    id int not null default nextval('sq_category_id'),
    name varchar(16) not null,
    date timestamp with time zone not null default (now() at time zone 'utc'),
    active bool not null default (true),
    constraint pk_category_id primary key (id),
    constraint uq_category_name unique (name)
);

..和功能

-- update
create or replace function fn_category_update(
    p_id integer,
    p_name character varying(16),
    p_date timestamp with time zone,
    p_active boolean
) returns json as
$$
declare result json = json_build_object('id', null, 'name', null, 'date', null, 'active', null);
begin
    update category set
        name = case
            when
                p_name is not null and
                p_name != name and
                rtrim(ltrim(p_name)) != ''
            then p_name
                else name
        end,
        date = case
            when
                p_date is not null and
                p_date != date
            then p_date
                else date
        end,
        active = case
            when
                p_active is not null and 
                p_active != active
            then p_active
                else active
        end
    where id = p_id returning json_build_object('id', id, 'name', name,     'date', date, 'active', active) into result;
    return result;
    exception when others then return result;
end
$$
language plpgsql;

任何人都知道我可能做错了什么?

**编辑,这里是c#代码以及异常堆栈跟踪(没有提供更多附加信息)。

using System;

namespace Landress.Co.Models.DataObjects
{
    public class CategoryDataObject
    {
        public int? Id { get; set; }
        public string Name { get; set; }
        public DateTime? Date { get; set; }
        public bool? Active { get; set; }

        public CategoryDataObject(int? id = null, string name = null, DateTime? date = null, bool? active = null)
        {
            this.Id = id;
            this.Name = name;
            this.Date = date;
            this.Active = active;
        }

        public CategoryDataObject()
        {
            this.Id = null;
            this.Name = null;
            this.Date = null;
            this.Active = null;
        }
    }
}

实际调用函数的代码:

public CategoryDataObject Update(CategoryDataObject item)
{
    NpgsqlConnection conn = new NpgsqlConnection(Configuration.GetSection("Data:DefaultConnection").Value);
    try
    {
        conn.Open();
        NpgsqlCommand cmd = new NpgsqlCommand("fn_category_update", conn);
        cmd.CommandType = CommandType.StoredProcedure;

        var paramId = cmd.CreateParameter();
        paramId.ParameterName = "p_id";
        paramId.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Integer;
        paramId.IsNullable = false;
        paramId.Value = item.Id;
        cmd.Parameters.Add(paramId);

        var paramName = cmd.CreateParameter();
        paramName.ParameterName = "p_name";
        paramName.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Varchar;
        paramName.Size = 16;
        paramName.IsNullable = true;
        paramName.Value = item.Name;
        cmd.Parameters.Add(paramName);

        var paramDate = cmd.CreateParameter();
        paramDate.ParameterName = "p_date";
        paramDate.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Timestamp;
        paramDate.IsNullable = true;
        paramDate.Value = item.Date;
        cmd.Parameters.Add(paramDate);

        var paramActive = cmd.CreateParameter();
        paramActive.ParameterName = "p_active";
        paramActive.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Boolean;
        paramActive.IsNullable = true;
        paramActive.Value = item.Active;
        cmd.Parameters.Add(paramActive);

        string jsonResult = String.Empty;

        try
        {
            jsonResult = cmd.ExecuteScalar().ToString();
            cmd.Dispose();
            conn.Close();
            conn.Dispose();
            try
            {
                return JsonConvert.DeserializeObject<CategoryDataObject>(jsonResult);
            }
            catch (Exception ex)
            {
                Console.WriteLine(String.Format("Unable to deserialize json result returned from postgresql: {0}", ex.Message));
                return new CategoryDataObject();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(String.Format("Unable to execute postgresql function \"fn_category_update\": {0}", ex.Message));
            return new CategoryDataObject();
        }

    }
    catch (Exception ex)
    {
        Console.WriteLine(String.Format("Unable to open a connection to the database: {0}", ex.Message));
        return new CategoryDataObject();
    }
}

最后是完整的堆栈跟踪。

-- Stack Trace
   at Npgsql.NpgsqlParameter.ValidateAndGetLength()
   at Npgsql.NpgsqlCommand.ValidateAndCreateMessages(CommandBehavior behavior)
   at Npgsql.NpgsqlCommand.ExecuteScalarInternal()
   at Landress.Co.Models.Repositories.CategoryRepository.Update(CategoryDataObject item) in C:\Users\<userName>\Desktop\landress.co\src\landress.co\Models\Repositories\CategoryRepository.cs:line 73

-- Message
Parameter p_date must be set

1 个答案:

答案 0 :(得分:1)

应该使用System.DBNull而不是null来表示传递给函数的值。根本不是图书馆的问题。