由C#Npgsql

时间:2017-07-26 13:56:59

标签: c# postgresql npgsql compositetype

我已经阅读了与该问题相关的几个问题和主题,但它们实际上都没有帮助我解决我的问题,而且它们实际上都与C#无关。这是实际问题:

我有一个Postgre复合类型:

CREATE TYPE law_relation_update_model AS (
   from_celex character varying,
   from_article character varying,
   to_celex character varying,
   to_article character varying,
   link_ids integer[],
   to_doc_par_id integer
);

我有一个存储过程,用于接受以下类型的数组:

CREATE OR REPLACE FUNCTION insert_law_relations(_items law_relation_update_model[])
RETURNS VOID
AS
$$
BEGIN

END;
$$
LANGUAGE PLPGSQL;

我已删除了正文代码,因为它不相关导致在C#的程序调用中抛出以下错误:

  

格式错误的数组文字

内心的信息:

  

数组值必须以“{”或维度信息

开头

即将传递的C#模型(它的数组):

public class LawRelationUpdateModel
{
    public string FromCelex { get; set; }

    public string FromArticle { get; set; }

    public string ToCelex { get; set; }

    public string ToArticle { get; set; }

    public IEnumerable<int> LinkIds { get; set; } = new List<int>();

    public int ToDocParId { get; set; }
}

使用Npgsql连接器进行调用的方法:

public static void InsertLawRelations(LawRelationUpdateModel[] updateModel)
{
    using (NpgsqlConnection conn = new NpgsqlConnection(connPG))
    {
        conn.Open();
        NpgsqlCommand comm = new NpgsqlCommand("insert_law_relations", conn);
        comm.CommandType = CommandType.StoredProcedure;
        var testParam = new NpgsqlParameter();
        testParam.DbType = DbType.Object;
        testParam.Value = updateModel;
        testParam.ParameterName = "_items";
        comm.Parameters.Add(testParam);

        comm.ExecuteNonQuery();
    }
}

连接中的错误是否可以在传递时以某种方式无法正确转换某些单/双引号或括号?

还是与我将DBType作为对象相关的事情?如果我没有收到以下错误:

  

无法将LawRelationUpdateModel []转换为任何有效的DbType。

对此问题或其他解决方法的任何帮助都将受到高度赞赏!

1 个答案:

答案 0 :(得分:0)

映射您的CLR类型

在CLR类型中设置显式映射仍然是可能的,在某些情况下还是必要的。这样做有以下优点:

您知道更长时间需要在参数上指定DataTypeName属性。 Npgsql将从您提供的CLR类型推断出数据类型。

诸如NpgsqlDataReader.GetValue()之类的无类型读取方法将返回您的CLR类型,而不是动态对象(请参阅下文)。一般来说,你应该使用类型化的NpgsqlDataReader.GetFieldValue(),所以这不应该是重要的。

您可以基于每种类型自定义名称映射(请参阅下文)。 要为所有连接设置全局映射,请在首次打开之前输入此代码:

 NpgsqlConnection.GlobalTypeMapper.MapEnum<SomeEnum>("some_enum");
 NpgsqlConnection.GlobalTypeMapper.MapComposite<SomeType>("some_composite");
  

这将在您的CLR类型SomeEnum和SomeType之间设置映射   PostgreSQL类型为some_enum和some_composite。

如果您不想为所有连接设置映射,则只能将其设置为一个连接:

var conn = new NpgsqlConnection(...);
conn.TypeMapper.MapEnum<SomeEnum>("some_enum");
conn.TypeMapper.MapComposite<SomeType>("some_composite");

http://www.npgsql.org/doc/types/enums_and_composites.html