使用NpgSql和Postgres 9.4从数据库中读取记录

时间:2015-07-25 21:16:41

标签: c# postgresql npgsql

我为我的.Net应用程序使用了Postgres 9.4和NpgSql 2.2.5.Postgres对我来说是新的,而且我尝试在数据库中执行postgres函数,它给我一个错误

这是我的C#代码

public List<District> DistrictReadAll()
      {
          try
          {
              List<District> districts = new List<District>();
              using (var conn = new NpgsqlConnection(this.RealEsateDB))
              {
                  conn.Open();
                  using (var cmd = conn.CreateCommand())
                  {
                      cmd.CommandText = "district_read_all";
                      cmd.CommandType = System.Data.CommandType.StoredProcedure;                      
                      NpgsqlDataReader rdr = cmd.ExecuteReader();
                      while (rdr.Read())
                      {
                          District objDist = new District();
                          objDist.DistrictId = (int)rdr["districtid"];
                          objDist.Name = rdr["name"].ToString();
                          districts.Add(objDist);
                      }
                      return districts;
                  }
              }
          }
          catch ( Exception ex)
          {

              throw;
          }
      }

Postgres功能

create or replace function district_read_all()
returns refcursor  
as
$$
declare
    ref1 refcursor ;
begin
    open ref1 for 
    select districtid,name from district order by name asc;
return  ref1;
end
$$ language plpgsql;

public.district表定义

CREATE TABLE district
(
  districtid serial NOT NULL,
  name character varying(250) NOT NULL,
  activeflag boolean DEFAULT true,
  CONSTRAINT pk_district_districtid PRIMARY KEY (districtid)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE district
  OWNER TO postgres;

C#错误堆栈跟踪

Npgsql.NpgsqlException was caught
  HResult=-2147467259
  Message=ERROR: 34000: cursor "<unnamed portal 1>" does not exist
  Source=Npgsql
  ErrorCode=-2147467259
  BaseMessage=cursor "<unnamed portal 1>" does not exist
  Code=34000
  ColumnName=""
  ConstraintName=""
  DataTypeName=""
  Detail=""
  ErrorSql=SELECT * FROM district_read_all()
  File=src\backend\commands\portalcmds.c
  Hint=""
  Line=168
  Position=""
  Routine=PerformPortalFetch
  SchemaName=""
  Severity=ERROR
  TableName=""
  Where=""
  StackTrace:
       at Npgsql.NpgsqlState.<ProcessBackendResponses>d__0.MoveNext()
       at Npgsql.ForwardsOnlyDataReader.GetNextResponseObject(Boolean cleanup)
       at Npgsql.ForwardsOnlyDataReader.GetNextRowDescription()
       at Npgsql.ForwardsOnlyDataReader.NextResultInternal()
       at Npgsql.ForwardsOnlyDataReader..ctor(IEnumerable`1 dataEnumeration, CommandBehavior behavior, NpgsqlCommand command, NotificationThreadBlock threadBlock, Boolean preparedStatement, NpgsqlRowDescription rowDescription)
       at Npgsql.NpgsqlCommand.GetReader(CommandBehavior cb)
       at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior cb)
       at Npgsql.NpgsqlCommand.ExecuteReader()
       at CarRental.DataAccess.DistrictAccess.DistrictReadAll() in c:\DotNetApplications\CarRentalGit\RJ.CarRental\CarRental.DataAccess\DistrictAccess.cs:line 58
  InnerException: 

如果我使用Sql Server

,这是一件非常简单的事情

有谁能让我知道这里有什么问题?

1 个答案:

答案 0 :(得分:2)

您必须在NpgsqlTransaction内包装并执行查询才能使其生效 - 请参阅手册的Using refcursors部分。

using (var conn = new NpgsqlConnection(this.RealEsateDB))
{
    conn.Open();

    using (NpgsqlTransaction t = conn.BeginTransaction()) 
    {
        using (var cmd = conn.CreateCommand())
        {
            ...
        }

        t.Commit();
    }
}