外部数据库上下文调用 ASP.NET MVC 期间 EF 数据库上下文的内部调用异步行为



在我的 ASP.NET MVC网站上,用户浏览书籍。他们可以选择将每本书添加到他们自己创建的列表中。

当用户浏览一本书时,每本书下方都有一个他所有列表的下拉列表,他可以选择将图书添加到其中。到目前为止一切都很好,但我现在想要的是让下拉菜单知道这本书是否已经包含在用户列表之一中。

这是相关的视图模型:

public class UserBookListsMinimalVM    {
public int ListId { get; set; }
public string ListName { get; set; }
public bool BookAlreadyInList { get; set; }
}

这是我为检索项目而运行的查询:

var userBookLists = await context.vwUserBookLists
.Where(x => x.ListOwner == userName)
.Select(x => new UserBookListsMinimalVM
{
ListId = x.ListId,
ListName = x.ListName,
BookAlreadyInList = context.List_Books.Any(y => y.ListId == x.ListId && y.BookId == bookId)
})
.OrderBy(x => x.ListName)
.ToListAsync();

vwUserBookLists是包含列表相关信息的视图,List_Book是列表和书籍之间的中间表(包含每个列表的书籍等(。

EF 生成的 SQL 嵌套SELECT语句,主要用于说明BookAlreadyInList属性。(我不知道查询是否可以简化,我愿意接受建议(

BookAlreadyInList赋值期间调用context是否"破坏"了整个函数的异步性,看到它不是await的?

它不会破坏你的异步操作,当 ToListAsync(( 完成工作时,该操作将完成。将只有一个异步操作,在此之前不会被任何操作破坏,无论您在查询中执行什么操作,都将遵守 await/async 协定。即使尝试具体化其中的某些实体,例如调用同步 ToList(((假设 EF 可以容忍这种情况(,也会在后台线程中进行此同步调用。不能在查询中使用 AnyAsync,因为 sql 提供程序无法转换异步操作,该操作特定于 c# 而不是 sql 服务器。

话虽如此,更重要的是,你仍然可以问自己 EF 是否只向数据库发送一个查询,或者将查询转换为多个数据库调用(可能是这种情况,具体取决于你使用的版本(,甚至在内存中执行一些操作。了解到底发生了什么的最好方法是查看输出窗口(如果可以看到生成的 sql(,或者在执行代码时启动监视数据库的 sql 探查器。 在最新版本的 .net core 中,可以将 dbcontext 配置为在表达式树无法完全转换为 sql 以及必须在内存中进行某些操作时引发异常。如果不这样做,您仍然会在输出窗口中收到警告。

最新更新