views:

69

answers:

1

Hi,

I'm using entity framework 4.

I have a stored procedure that just updates one value in my table, namely the application state ID. So I created a stored procedure that looks like this:

ALTER PROCEDURE [dbo].[UpdateApplicationState]
(
   @ApplicationID INT,
   @ApplicationStateID INT
)

AS

BEGIN

   UPDATE
      [Application]
   SET
      ApplicationStateID = @ApplicationStateID
   WHERE
      ApplicationID = @ApplicationID;

END

I created a function import called UpdateApplicationState. I had initially set its return type to null, but then it wasn't created in the context. So I changed its return type to int. Now it was created in the context. Is it wise to return something from my stored procedure?

Here is my method in my ApplicationRepository class:

public void UpdateApplicationState(int applicationID, int applicationStateID)
{
   var result = context.UpdateApplicationState(applicationID, applicationStateID);
}

Here is my calling code to this method in my view:

applicationRepository.UpdateApplicationState(id, newApplicationStateID);

When I run it then I get the following error:

The data reader returned by the store data provider does not have enough columns for the query requested.

Any idea/advise on what I can do to get this to work?

Thanks

+1  A: 

It is because you do not actually returning anything from your stored procedure. Add a line like below to your SP (SELECT @@ROWCOUNT), and it will be executing properly.

BEGIN    
    ...

    SELECT @@ROWCOUNT
END

While this solution will address your issue and actually returns the number of effected rows by your SP, I am not clear on why this is an issue for you:

I had initially set its return type to null, but then it wasn't created in the context.

When doing a Function Import, you can select "None" as return type and it will generate a new method on your ObjectContext with a return type of int. This method basically executes a stored procedure that is defined in the data source; discards any results returned from the function; and returns the number of rows affected by the execution.

EDIT: Why a Function without return value is ignored in a POCO Scenario:

Drilling into ObjectContext T4 template file coming with ADO.NET C# POCO Entity Generator reveals why you cannot see your Function in your ObjectContext class: Simply it's ignored! They escape to the next iteration in the foreach loop that generates the functions.

The workaround for this is to change the T4 template to actually generate a method for Functions without return type or just returning something based on the first solution.

region.Begin("Function Imports");

foreach (EdmFunction edmFunction in container.FunctionImports)
{
    var parameters = FunctionImportParameter.Create(edmFunction.Parameters, code, ef);
    string paramList = String.Join(", ", parameters.Select(p => p.FunctionParameterType + " " + p.FunctionParameterName).ToArray());

    // Here is why a Function without return value is ignored:
    if (edmFunction.ReturnParameter == null)
    {
        continue;
    }
    string returnTypeElement = code.Escape(ef.GetElementType(edmFunction.ReturnParameter.TypeUsage));
    ...
Morteza Manavi
When I select none then the function import is not in my object context. It doesn't exist. I did a search for it. When I select it to have a return type then it is in my object context. I am using the POCO entity generator.
Brendan Vogt
I don't need to return anything that is why I wanted to set the return type as none, but when I do it this way then it doesn't exist in my object context.
Brendan Vogt
Yes, you are right, in a POCO scenario, it is ignored and I edit my answer to show the reason for this behavior. I thought you are using EntityObjects since it is not an issue there.
Morteza Manavi