为什么我不能将异步查询移动到方法中?

Tom*_*Tom 8 c# asynchronous async-await c#-5.0

以下代码有效

[Route("case-studies/{slug}")]
public async Task<ActionResult> Details(string slug)
{
    var item = await Db.Pages.OfType<CaseStudy>()
             .WithSlug(slug)
             .FirstOrDefaultAsync();

    if (item == null)
    {
        return HttpNotFound();
    }

    var related = await Db.Pages.OfType<CaseStudy>()
           .Where(r => r.Client == item.Client && r.Id != item.Id)
           .Where(r => !r.IsArchived)
           .Include(r => r.Media)
           .Take(3)
           .Project()
           .To<RelatedPageModel>()
           .ToListAsync();

    var archived = await Db.Pages.OfType<CaseStudy>()
            .Where(r => r.Client == item.Client && r.Id != item.Id)
            .Where(r => r.IsArchived)
            .Take(3)
            .Project()
            .To<RelatedPageModel>()
            .ToListAsync();

    ViewData.Model = new DetailPageModel<CaseStudy>()
    {
        Item = item,
        RelatedItems = related,
        ArchivedItems = archived
    };

    return View();
}
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试重构async方法调用如下

[Route("case-studies/{slug}")]
public async Task<ActionResult> Details(string slug)
{
    var item = await Db.Pages.OfType<CaseStudy>()
             .WithSlug(slug)
             .FirstOrDefaultAsync();

    if (item == null)
    {
        return HttpNotFound();
    }       

    var related = await GetRelatedCaseStudies(item, false);
    var archived = await GetRelatedCaseStudies(item, true);

    ViewData.Model = new DetailPageModel<CaseStudy>()
    {
        Item = item,
        RelatedItems = related,
        ArchivedItems = archived
    };

    return View();
}


private Task<List<RelatedPageModel>> GetRelatedCaseStudies(CaseStudy casestudy, bool archived)
{
    return Db.Pages.OfType<CaseStudy>()
            .Where(r => r.Client == casestudy.Client && r.Id != casestudy.Id)
            .Where(x => x.IsArchived == archived)
            .Include(r => r.Media)
            .Take(3)
            .Project().To<RelatedPageModel>()
            .ToListAsync();
}
Run Code Online (Sandbox Code Playgroud)

它没有给我以下错误

在先前的异步操作完成之前,在该上下文上开始第二操作.使用'await'确保在此上下文上调用另一个方法之前已完成任何异步操作.任何实例成员都不保证是线程安全的.

为什么是这样?我怎样才能做到这一点?

更新:

Db在基本控制器中声明如下

private WebSiteDb db;

protected WebSiteDb Db
{
    get
    {
        LazyInitializer.EnsureInitialized(ref db, () => new WebSiteDb());

        return db;
    }
}
Run Code Online (Sandbox Code Playgroud)

WebSiteDb扩展DbContext,如下所示

   [DbConfigurationType(typeof(DbConfig))]
    public class WebSiteDb : DbContext
    {
        static WebSiteDb() {
            Database.SetInitializer<WebSiteDb>(new WebSiteDbInitializer());
        }
        public IDbSet<Page> Pages { get; set; }
        public IDbSet<Media> Media { get; set; }
        ...some missing sets

        public WebSiteDb() : base("MyDatabaseName") { }
     }
Run Code Online (Sandbox Code Playgroud)

如果我在方法内部等待,则会从方法内部抛出错误

WithSlug()如下

public static IQueryable<T> WithSlug<T>(this IQueryable<T> pages, string slug) where T : Page
        {
            return pages.Where(p => p.Slug == slug);
        }
Run Code Online (Sandbox Code Playgroud)

Moh*_*oho 0

下面的测试代码工作得很好。显示实施情况.WithSlug( slug )

class Program
{
    static void Main( string[] args )
    {
        using( var db = new TestEntities() )
        {
            db.EntityBs.Add( new EntityB()
                {
                    EntityBId = 78
                } );

            db.SaveChanges();

            Task.WaitAll( Test( db ) );
        }

        var input = Console.ReadLine();
    }

    static Task<List<EntityB>> GetEntityBsAsync( TestEntities db )
    {
        return db.EntityBs.ToListAsync();
    }

    static async Task Test( TestEntities db )
    {
        var a0 = await GetEntityBsAsync( db );
        var a1 = await GetEntityBsAsync( db );
    }
}
Run Code Online (Sandbox Code Playgroud)