[英]How to write Repository method for .ThenInclude in EF Core 2
[英]How to create an asynchronous repository with EF Core?
我正在嘗試使用存儲庫抽象 EF Core,但無法弄清楚如何使其異步。 這是同步版本:
public class UserRepository
{
private DbSet<User> users;
public UserRepository(ApplicationDbContext context)
{
users = context.Set<User>();
}
public IQueryable<User> GetAll()
{
return users;
}
...
}
問題是,為了使查詢異步,我們需要使用 EF 的特殊擴展方法,如ToListAsync()
或CountAsync()
,如果使用存儲庫的項目引用 EF 命名空間,那么抽象的意義何在?
我研究的另一件事是返回IAsyncEnumerable<User>
,然后使用這個官方庫異步使用 LINQ。 但是,我無法讓它正常運行,因為在使用這些新的 LINQ 方法時,查詢是在 .NET 中處理的,而不是將 LINQ 語法轉換為 SQL。 我們以下面的查詢為例:
var result = await Repository.GetAll()
.Limit(10)
.ToListAsync();
在使用 EF 的擴展方法時,我在 SSMS 中看到了這個查詢:
exec sp_executesql N'SELECT [u].[Id], [u].[Deleted], [u].[EmailAddress], [u].[FirstName], [u].[LastName], [u].[PhoneNumber], [u].[Status], [u].[VerifiedEmailAddress], [u].[VerifiedPhoneNumber]
FROM [Users] AS [u]
ORDER BY (SELECT 1)
OFFSET @__p_0 ROWS FETCH NEXT @__p_1 ROWS ONLY',N'@__p_0 int,@__p_1 int',@__p_0=0,@__p_1=10
這意味着只會從數據庫中選擇 10 條記錄,這正是我想要的。
但是當使用System.Linq.Async
的擴展方法時,我的 C# 代碼仍然得到相同的結果,但是這個查詢顯示在 SSMS 中:
SELECT [u].[Id], [u].[Deleted], [u].[EmailAddress], [u].[FirstName], [u].[LastName], [u].[PhoneNumber], [u].[Status], [u].[VerifiedEmailAddress], [u].[VerifiedPhoneNumber]
FROM [Users] AS [u]
完全沒有限制,這意味着如果我在 Users 表中有數百萬行,那么每次運行查詢時都會選擇所有這些行,而我只需要前 10 行。
有沒有辦法使用 LINQ to SQL 和異步流? 或者也許是如何抽象 EF 但仍然允許異步查詢的另一個想法?
我不建議抽象 EFCore,您可以使用IApplicationDbContext
抽象上下文。 主要是因為 EF 已經是一個抽象層,其次是因為讓“用戶”訪問 IQueryable 可能會產生意外行為或異常。
如果你真的需要這樣做,我在想的是:
public Task<List<User>> GetAsync(Action<IQueryable<User>> filter)
{
filter(_users);
return _users.ToListAsync();
}
並使用它:
var result = await Repository.GetAsync(x => x.Take(10));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.