Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EF6 alpha Async Await on an Entity Stored Procedure / Function Import?

I'd like to apply the new async await functionality to Stored Procedures / Function Imports imported in my Entity model, but have as yet been unable to with the EF6 alpha.

Is it yet possible in EF6 alpha2 (or the nightly build as of 20211) to call any of the new Async methods on an Entity Function Import (which calls a SQL Stored Procedure) that returns a collection of Complex Type? e.g.

private async Task<IList<Company>> getInfo (string id)
{
    using (CustomEntity context = new CustomEntity())
    {
        var query = await context.customStoredProcedure(id).ToListAsync();
        // ".ToListAsync()" method not available on above line

        // OR ALTERNATIVELY
        var query = await (from c in context.customStoredProcedure(id)
                           select new Company
                           {
                              Ident = c.id,
                              Name = c.name,
                              Country = c.country,
                              Sector = c.sector, 
                              etc. etc....
                           }).ToListAsync();
        // ".ToListAsync()" method or any "...Async" methods also not available this way

        return query;
    }
}

"ToListAsync", or any of the new async modified methods do not seem to be available to the above Entity Stored Procedure / Function Import; only the standard "ToList" or "AsNumerable" etc methods are available.

I followed this (http://entityframework.codeplex.com/wikipage?title=Updating%20Applications%20to%20use%20EF6) to make sure the code is referencing the new EF6 dlls and not EF5, as well as updated the various using statements. Aside from above, everything builds correctly. (.NET Framework 4.5)

The only time I can see the async methods is if instead of only importing stored procedures from the DB, I also import a table--then when referencing that table via the Entity context as above (context.SomeTable), some of the async methods appear in intellisense.

I'd really like to start using the new async await functionality on multiple Stored Procedures prior to returning data as JSON, but have not been able to get it to work so far.

Am I doing something wrong? Is async functionality not possible on Entity stored procedure / function imports? Thanks for your advice.

like image 987
blueFish Avatar asked Oct 04 '22 22:10

blueFish


2 Answers

Now this is by no means the best solution. I added an extension method so that I could call await on my stored procedures. In the newer releases of EF6.1+ we should see this officially implemented. Until then a dummy extension method does the job.

static async Task<List<T>> ToListAsync<T>(this ObjectResult<T> source)
{
    var list = new List<T>();
    await Task.Run(() => list.AddRange(source.ToList()));
    return list;
}

If you reflect version 6 of EF you will see that ObjectResult<T> actually implements IDbAsyncEnumerable<T>, IDbAsyncEnumerable. And the method for ToListAsync<T>(this IDbAsyncEnumerable<T> source) should be able to wire it up the same as a LINQ query.

Edit When the ObjectResult is empty null is returned. You could add if (source == null) return new List<T>(); if you want to return an empty List instead of null.

like image 160
Jeremy Avatar answered Oct 12 '22 04:10

Jeremy


This is an old thread, but I felt I should share. You should use APM then wrap the synchronous calls in a Task.

Example:

//declare the delegate
private delegate MyResult MySPDelegate();

// declare the synchronous method
private MyResult MySP()
{
    // do work...
}

Then wrap the synchronous method in a Task:

// wraps the method in a task and returns the task.
public Task<MyResult> MySPAsync()
{
    MySPDelegate caller = new MySPDelegate(MySP);
    return Task.Factory.FromAsync(caller.BeginInvoke, caller.EndInvoke, null);
}

Call the async method when you want to execute:

var MyResult = await MySPAsync();

You can use up to three (3) parameters in the methods. Best practice is if you use more than three parameters; you should pass in a class.

like image 38
Ryan Thiele Avatar answered Oct 12 '22 02:10

Ryan Thiele