Multiple fields are not valid for EDM primitive types.

I ran into a problem when executing stored procedures with output parameters using Entity Framework Code First which lead to this exception:
The data reader has more than one field. Multiple fields are not valid for EDM primitive types.
Problem
This is my stored procedure:
   CREATE PROCEDURE sp_test (@name varchar(30) OUTPUT)
    AS
      SELECT @name = 'John Doe'
    GO
As you can see I want to return one value as varchar/string.
This is how you call a stored procedure with EF Code First:
var sqlParameter = new SqlParameter{
                            ParameterName = "UniekKenmerkOUT",
                            Value = -1,
                            DbType = DbType.String,
                            Size = 30,
                            Direction = ParameterDirection.Output
                    };
var result = Context.Database.SqlQuery("exec sp_test @name = @name OUT",sqlParameter);

When I execute the code I get this exception:
The data reader has more than one field. Multiple fields are not valid for EDM primitive types.
Solution
Entity Framework expects a return value. The stored procedure is only returning an output parameter, and that is not enough.

We can fix it this way:
CREATE PROCEDURE sp_test (@name varchar(30) OUTPUT)
     AS SELECT @name = 'John Doe'
     SELECT @name
  GO
The first SELECT statement in the stored procedure is not returning a value. It's actually assigning a value to the output parameter. That's why we need a second select to really return the value. I think it's preferable to write it this way:
CREATE PROCEDURE sp_test (@name varchar(30) OUTPUT)
AS SET @name = 'John Doe'
 SELECT @name
GO
Without output parameters As you can see the output parameter in the example above is not necessary, but it returns the exact same value as the select statement. So, we can rewrite the stored procedure like this:
CREATE PROCEDURE sp_test
AS
 SELECT 'John Doe'
GO
And then we can execute this stored procedure with Entity Framework Code First:
var result = Context.Database.SqlQuery("exec sp_test);

3 comments:

  1. Nice article, but, what if I don't want nothing back from the stored procedure?

    I have a stored procedure that makes a copy of a register in the database. If it works fine, then returns 0, other wise it returns a value greater than 0.

    I have tried to execute it as
    db.Database.SqlQuery("dbo...

    But it is giving me the same exception described in your article.

    Any help would be welcomed.

    Thanks.

    ReplyDelete
  2. Please send your complete stored procedure and code

    ReplyDelete
  3. wonderful publish, very іnformative. I wonder wɦy thе other expertѕ of this sector Ԁon't undеrstand this.
    You must continue your writing. I'm sure, you've a
    huge reɑders' base alreadу!

    Also visit my web-site: derm esclusive anti aging

    ReplyDelete