Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用EF Core创建异步存储库?_C#_Sql Server_Linq_Asynchronous_Entity Framework Core - Fatal编程技术网

C# 如何使用EF Core创建异步存储库?

C# 如何使用EF Core创建异步存储库?,c#,sql-server,linq,asynchronous,entity-framework-core,C#,Sql Server,Linq,Asynchronous,Entity Framework Core,我试图用一个存储库来抽象EF核心,但不知道如何使其异步。 这是同步版本: public class UserRepository { private DbSet<User> users; public UserRepository(ApplicationDbContext context) { users = context.Set<User>(); } public IQueryable<User> G

我试图用一个存储库来抽象EF核心,但不知道如何使其异步。 这是同步版本:

public class UserRepository
{
    private DbSet<User> users;
    public UserRepository(ApplicationDbContext context)
    {
        users = context.Set<User>();
    }
    public IQueryable<User> GetAll()
    {
        return users;
    }
    ...
}
在使用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#code相同的结果,但是这个查询在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行


有没有一种方法可以使用LINQtoSQL和异步流?或者是关于如何抽象EF但仍然允许异步查询的另一种想法?

我不建议抽象EFCore, 您可以使用
iaapplicationdbcontext
抽象上下文。 主要是因为EF已经是一个抽象层,其次是因为让“用户”访问IQueryable可能会产生意外的行为或异常

如果你真的需要这样做,我想的是:

公共任务GetAsync(操作筛选器) { 过滤器(用户); 返回_users.toListSync(); } 并且像这样使用它:

var result=await Repository.GetAsync(x=>x.Take(10));

我尝试了类似的操作,我认为您必须使用返回
IQueryable
Func
,因为
Take
不会更改原始对象。但这种方法的主要问题是,它只适用于
ToListAsync
,这意味着我还必须创建一个调用
SumAsync
maxaync
的方法,并从本质上重新创建整个LINQ接口……但是您想如何使用它呢?我不明白。如果您为上下文添加了一个接口,那么您实际上就抽象了EF核心。关于ToListSync,这只是一个扩展方法,您可以创建自己的ToListSync。您需要使用IQueryable,以便枚举查询的每个方法都能完成此任务。不完全是这样,这不是一个抽象,因为接口将声明类型为
DbSet
的属性,而这仍然是应用程序代码中的数据访问代码。关于扩展方法,为了重新实现它们,我必须引用EF。这就是为什么我更喜欢将它们放在存储库中,并调用EF,但是用常规方法或扩展方法实现它们并没有太大区别。但不幸的是,我不知道你是怎么做到的。我还是不明白你为什么要这么做。您希望公开IQueryable,而不知道谁会将其转换为调用,但在使用此存储库时,您必须像使用EF Core一样编写代码,否则无法确保未知ORM支持特定的扩展方法。我过去经常看到和使用的东西有SqlUserRepository、CosmosUserRepository、MongouseRepository等。如果这没有什么帮助,我很抱歉
SELECT [u].[Id], [u].[Deleted], [u].[EmailAddress], [u].[FirstName], [u].[LastName], [u].[PhoneNumber], [u].[Status], [u].[VerifiedEmailAddress], [u].[VerifiedPhoneNumber]
FROM [Users] AS [u]