简体   繁体   中英

Entity Framework and Postgresql: returning record from a stored procedure

I'm unable to use the standard function importing mechanism, because composable functions are not visible in the function import list. However, I managed to get functions returning a scalar value to work this way:

I use "update model from database" without "import selected functions and stored procedures..." selected. This generates a function entry in edmx-file, which I manually change for correct return type.

<Function Name="get_customer_name" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="true" ParameterTypeSemantics="AllowImplicitConversion" Schema="public" ReturnType="text">
      <Parameter Name="p1" Type="bigint" Mode="In" />
    </Function>

Then I add following class definition:

public class DBFunctions
{
    [EdmFunction("dbNamespace.Store", "get_customer_name")]
    public static string GetCustomerName(long id)
    {
        throw new NotSupportedException("Direct calls are not supported.");
    }
}

After this, I can call DBFunctions.GetCustomerName(id) in my queries.

However, how can I make this work with complex types? For example, let's say that I have a type named customer_address defined in postgresql like (code integer, address text), and I have a function get_customer_address(id) with a return type of customer_address. How could I call that function in queries? For example, I'd like to be able to write

var addressList = (from customer
                   select GetCustomerAddress(customer.id)).ToList();

Here GetCustomerAddress would return a custom Address object. How can I provide the mapping between returned columns and class attributes, and what is the correct return type in edmx-file?

I can answer the first half of your question with a simple example. Suppose you have a stored proc my_stored_proc that returns an int (I) and a text column (T).

Your class in C# would look like this:

public class MyClass
{

    public int I
    {
        get;
        set;
    }

    public string T
    {
        get;
        set;
    }

}

To load in your objects you would call your stored proc like this:

{

    // In reality you'd put a where clause in here and use parameters to limit the results
    string myQuery = "select * from my_stored_proc()"

    var listResultSet = database_context.Database.SqlQuery<MyClass>(myQuery).ToList();

}

Hope this helps,

Adam.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM