sqlentity-frameworkpostgresqldevartdotconnect

DevArt dotConnect for PostgreSQL Entity Framework execute function without import not populating class properties


I have following POCO class against database table

public class Contact
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public bool Checked { get; set; }
    public string Mobile { get; set; }
    public string Email { get; set; }
}

A function in PostgreSQL database

CREATE OR REPLACE FUNCTION test_proc_pg()
  RETURNS TABLE(id integer, name character varying, Checked boolean, Mobile character varying, Email character varying) AS
$BODY$
BEGIN
    RETURN QUERY select temp1.id, temp1.Name, temp1.Checked, temp1.Mobile, temp1.Email from temp1;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE;

Defined a generic function to call PostgreSQL function and get back data

public static List<T> ExecuteProc<T>(string procname, params PgSqlParameter[] param)
{
    List<T> list;
    string paranames = string.Empty;
    foreach (PgSqlParameter p in param)
    {
    if (paranames != string.Empty)
        paranames += ", ";
    paranames = paranames + "?";
    }

    using (var context  = new EntityContext())
    {
    list = context.Database.SqlQuery<T>("select " + procname + "(" + paranames + ")", param).ToList<T>();
    }
    return list;
}

Calling above function in Controller

public ActionResult ProcTest()
{
    List<Contact> contacts = DAL.ExecuteProc<Contact>("test_proc_pg");
    return View(contacts);
}

Function is executing and returning List<Contact> but all the fields in class are null.

{TestPG.Models.Contact}
    Checked: false
    Email: null
    Id: 0
    Mobile: null
    Name: null

However if i use SQL Server/SqlClient and call proc similarly it is populating all fields. Here is similar function written for SQL Server

public static List<T> ExecuteProc<T>(string procname, params SqlParameter[] param)
    {
        List<T> list;
        string paranames = string.Empty;
        foreach (SqlParameter p in param)
        {
            if (paranames != string.Empty)
                paranames += ", ";
            paranames = paranames + "@" + p.ParameterName;
        }

        using (var context = new SSContext())
        {
            list = context.Database.SqlQuery<T>("exec " + procname + " " + paranames, param).ToList<T>();
        }
        return list;
    }

When i call it from controller it gives class with all fields populated

public ActionResult ProcTest()
    {
        List<Contact> contacts = DAL.ExecuteProc<Contact>("test_proc_ss");
        return View(contacts);
    }

Here is result from SQL Server

{TestSS.Models.Contact}
    Checked: false
    Email: "noone@nowhere.com"
    Id: 1
    Mobile: "1234567890"
    Name: "samtech"

What the wrong i am doing with dotConnect PostgreSQL?

I am using EF6 with latest trial version of dotConnect for PostgreSQL. I do not want to import functions.

Can someone help?


Solution

  • We have answered to you at our forum: http://forums.devart.com/viewtopic.php?f=3&t=29126

    ANSWER:

    Please change this code

    list = context.Database.SqlQuery<T>("select " + procname + "(" + paranames + ")", param).ToList<T>();
    

    with this:

    list = context.Database.SqlQuery<T>("select * from " + procname + "(" + paranames + ")", param).ToList<T>();
    

    This is related to the peculiarity of working with the PostgreSQL stored procedures. In case of "select test_proc_ss" the PostgreSQL record is returned. It is necessary to disclose the query, so that all columns are returned and EF could materialize the corresponding objects.