问题
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.
回答1:
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.
回答2:
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.
来源:https://stackoverflow.com/questions/15051375/ef6-alpha-async-await-on-an-entity-stored-procedure-function-import