【问题标题】:How to overcome the IQueryable doesn't implement IAsyncQueryProvider while Mocking the FromSql() method?如何在模拟 FromSql() 方法时克服 IQueryable 不实现 IAsyncQueryProvider?
【发布时间】:2020-01-09 11:49:27
【问题描述】:

我正在使用以下链接在 x 单元中模拟 FromSql 方法 How could I Mock the FromSql() method?

使用FirstOrDefaultAsync的方法出现以下错误

源 IQueryable 的提供程序未实现 IAsyncQueryProvider。仅实现 IAsyncQueryProvider 的提供程序 可用于实体框架异步操作。

但是对于ToListAsync 方法来说它工作得很好。

SpAsyncEnumerableQueryable<Model> models = new SpAsyncEnumerableQueryable<Model>();
models.Add(new Model { ItemId = 1 });

MyDbContext.Model = MyDbContext.Model.MockFromSql(models);

下面是实际方法c#

return await this.MyDbContext.Model
    .FromSql("TestProc", 1, 1)
    .FirstOrDefaultAsync()
    .ConfigureAwait(false);

FirstOrDefaultAsync 出现错误

源 IQueryable 的提供程序未实现 IAsyncQueryProvider。仅实现 IAsyncQueryProvider 的提供程序 可用于实体框架异步操作。

【问题讨论】:

    标签: c#


    【解决方案1】:

    异常消息告诉您问题,FromSql 返回的序列提供程序没有实现IAsyncQueryProvider。您的 FromSql 模拟设置需要返回具有 IAsyncQueryProvider 提供程序的序列。

    我认为有几种方法可以实现。一种是创建您自己的实现 IAsyncQueryProvider 的 AsyncQueryProvider,然后确保您的 FromSql 模拟调用返回一个将其设置为提供者的序列。这将引导您实现实现 IAsyncEnumerator 和 IAsyncEnumerable 的类。

    另一个可行的选项是在设置 FromSql 模拟时,将返回序列转换为 Queryable,然后转换为 AsyncEnumerable。在我的脑海中,它看起来像enumerable.AsQueryable().ToAsyncEnumerable()。这是我目前在设置 DbQuery 模拟时所做的,它似乎适用于异步 LINQ 操作。

    话虽如此,已经为 EntityFrameworkCore.Testing 完成了它,它在 FromSql 调用的背面支持 FirstOrDefaultAsync,节省一些时间并使用其中一个为你做这件事的库。

    [Test]
    public virtual async Task FromSqlThenFirstOrDefaultAsync_ReturnsFirstElement()
    {
        var storedProcedureReturns = Fixture.CreateMany<TestEntity>().ToList();
        var mockedDbContext = 
            Create.MockedDbContextFor(new TestDbContext(new DbContextOptionsBuilder<TestDbContext>().UseInMemoryDatabase(Guid.NewGuid().ToString()).Options));
        mockedDbContext.Set<TestEntity>().AddFromSqlResult("usp_SomeStoredProcedure", storedProcedureReturns);
    
        var actualResult = await mockedDbContext.Set<TestEntity>().FromSql("[dbo].[usp_SomeStoredProcedure] @Parameter1, @Parameter2").FirstOrDefaultAsync();
    
        Assert.That(actualResult, Is.EqualTo(storedProcedureReturns.First()));
    }
    

    【讨论】:

    • 不确定为什么这被否决,在撰写本文时建议是正确的。
    猜你喜欢
    • 2018-12-04
    • 1970-01-01
    • 2019-02-09
    • 2019-12-10
    • 2012-10-31
    • 2011-10-26
    • 1970-01-01
    • 2019-06-09
    • 2021-12-09
    相关资源
    最近更新 更多