2

I am using visual studio 2015 community version, and MVC 5, entity framework 6. I am just learned how to use async and await for making asynchronous call.

Now in my project I have only CRUD operations and for all operations I have written store procedures, I dont have more bussiness logic in my API's except calling store procedures. So I am using async and await for calling store procedure.

But doing that, I am getting error,

'int' does not contain a definition for 'GetAwaiter' and no extension method 'GetAwaiter' accepting a first argument of type 'int' could be found (are you missing a using directive or an assembly reference?)

My code is,

 [HttpPost]
        public async Task<IHttpActionResult> AddContactEmails(Contacts data)
        {
            using (JodoDataEntities DB = new JodoDataEntities())
            {
                int Result = await DB.AddContacts(data.userId, data.data);
                return Ok();
            }
        }

My store procedure is very simple, I am returning anything from it, still EF taking it as int return type.

ALTER PROCEDURE [dbo].[AddContacts]
    @userId nvarchar(128),
    @contacts nvarchar(MAX)
AS
BEGIN
    SET NOCOUNT ON;
    if not exists(select top 1 * from Contacts where userId = @userId)
    begin
        insert into Contacts (userId, contacts) VALUES (@userId, @contacts)
    end
END

EF code (Generated automatically),

 public virtual int AddContacts(string userId, string contacts)
        {
            var userIdParameter = userId != null ?
                new ObjectParameter("userId", userId) :
                new ObjectParameter("userId", typeof(string));

            var contactsParameter = contacts != null ?
                new ObjectParameter("contacts", contacts) :
                new ObjectParameter("contacts", typeof(string));

            return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("AddContacts", userIdParameter, contactsParameter);
        }

1). Why I am getting this error while calling method ?

2). where do I need to change to make it work ?

3). So I really need to use async and await when I have only SP calls in my API's ?

Keval Patel
  • 925
  • 4
  • 24
  • 46
  • Since your methods are not awaitable, you have to wrap them in something like Task.Run if you think you need to use async/await. – Tieson T. Oct 17 '15 at 03:57

1 Answers1

1

If this returns a Task<int>:

DB.AddContacts(...);

Then this simply returns an int:

await DB.AddContacts(...);

So the Result variable should be of type int, not Task<int>.


Edit: I just noticed the definition for AddContacts() in your question. It's not an async method, so it can't be awaited. There are no async operations in your code. Just remove the async and await attempts entirely, this is synchronous code...

int Result = DB.AddContacts(...);

As an aside, this is a bad idea:

catch (Exception ex)
{
    throw ex;
}

It's basically throwing away useful debugging information. Just remove the try/catch construct entirely and let the exception be thrown by the operation which originally throws it.

David
  • 208,112
  • 36
  • 198
  • 279
  • after writing it like, int Result = await (DB.AddContacts(data.userId, data.data)); ..... giving me error and we cannot return int from async method. It has to void, task or task. – Keval Patel Oct 17 '15 at 03:40
  • @KevalPatel: I just noticed the definition for `AddContacts()` in your question. It's... not `async`. So you can't `await` it. Just call it like a normal method, there's no `async` in this code. – David Oct 17 '15 at 03:43
  • I have changed some of the things in question, please check my AddContactEmails(). And AddContacts() is auto generated by entity framework. Do you want me to make it async ? – Keval Patel Oct 17 '15 at 03:48
  • @KevalPatel: I'm not sure what you're trying to accomplish at this point. There don't appear to be any asynchronous I/O operations in this code. So there's no reason for methods consuming those operations to be asynchronous. If the EF code has `async` versions of its operations, then you can invoke *those* from consuming `async` methods. – David Oct 17 '15 at 03:51
  • I just want to make asynchronous calls, So for that I am using async and await, I am still learning use of async await. – Keval Patel Oct 17 '15 at 03:59
  • @KevalPatel: But in order to be asynchronous the underlying operation needs to be asynchronous. This database operation is synchronous. When EF generates the code, does it generate any async versions of the same operations? – David Oct 17 '15 at 04:03
  • I can understand what you are saying, Can you tell me how can I make it asynchronous ? Or else do I need to go with LINQ queries only ? – Keval Patel Oct 17 '15 at 04:11
  • @KevalPatel: It looks like there might be a workaround or two: http://stackoverflow.com/questions/25901862/entityframework-stored-proc-function-import-is-it-possible-to-read-async – David Oct 17 '15 at 11:51