2016-11-23 115 views
3

我有一个方法查询:转换IQueryable的实施IAsyncEnumerable

private readonly IEntityReader<Customer> _reader; 

public async Task<IEnumerable<Customer>> HandleAsync(GetCustomer query) 
{ 
    var result = _reader.Query() 
     .Include(customer => customer.Organization) 
     .Where(customer => customer.Name == query.Name); 

    return await result.ToListAsync(); 
} 

具有这种单元测试:

[Fact] 
public async Task HandleGetCustomer_ReturnsCustomer_WhenNameMatches() 
{ 
    // Arrange 
    var customers = new List<Customer>() 
    { 
     new Customer 
     { 
      Id = new Guid("d4e749ba-6874-40f4-9134-6c9cc1bc95fe"), 
      Name = "John Doe", 
      Age = 18, 
      Organization = new Organization 
      { 
       Id = new Guid("b2ba06c9-5c00-4634-b6f7-80167ea8c3f1"), 
       Name = "TheCompany", 
       Number = 42 
      } 
     }, 
     new Customer 
     { 
      Id = new Guid("0679ceb5-3d4f-41f3-a1b0-b167e1ac6d7e"), 
      Name = "Another Guy", 
      Age = 39, 
      Organization = new Organization 
      { 
       Id = new Guid("b2ba06c9-5c00-4634-b6f7-80167ea8c3f1"), 
       Name = "TheCompany", 
       Number = 42 
      } 
     } 
    }.AsQueryable(); 

    var entityReader = new Mock<IEntityReader<Customer>>(MockBehavior.Strict); 
    entityReader.Setup(reader => reader.Query()).Returns(customers); 

    var query = new GetCustomer 
    { 
     Name = "John Doe" 
    }; 

    var handler = new HandleGetCustomer(entityReader.Object); 

    // Act 
    var result = await handler.HandleAsync(query); 

    // Assert 
    Assert.NotNull(result); 
    Assert.True(result.Count() == 1); 
    Assert.True(result.FirstOrDefault().Id == new Guid("d4e749ba-6874-40f4-9134-6c9cc1bc95fe")); 
} 

通过apperently调用.ToListAsync();失败的原因为:

源IQueryable未实现 IAsyncEnumerable。 仅实现IAsyncEnumerable的源可用于实体框架 的异步操作。

扩展方法是Entity Framework Core中的一种方法。

如何将我的客户列表转换为IAsyncEnumerable

作为参考,IEntityReader接口被定义如:

public interface IEntityReader<out TEntity> where TEntity : Entity 
{ 
    IQueryable<TEntity> Query(); 
} 
+2

看看这里http://stackoverflow.com/a/40500030/5233410解决方案可以修改并应用到您的使用案例 – Nkosi

+0

看起来像那样的代码正在研究'DbSet ',但我会看看。 – janhartmann

+0

是的,它也是IQueriable类型的。可以应用相同的策略。或者您可以查看ef源代码内部使用的AsAsyncEnumerable扩展方法。 – Nkosi

回答

1

由于@Nkosi,这是解决方案:

How to mock an async repository with Entity Framework Core与客户列表的变化的代码片段:

var customers = new TestAsyncEnumerable<Customer>(new List<Customer> 
{ 
    new Customer 
    { 
     Id = new Guid("d4e749ba-6874-40f4-9134-6c9cc1bc95fe"), 
     Name = "John Doe", 
     Age = 18, 
     Organization = new Organization 
     { 
      Id = new Guid("b2ba06c9-5c00-4634-b6f7-80167ea8c3f1"), 
      Name = "TheCompany", 
      Number = 42 
     } 
    }, 
    new Customer 
    { 
     Id = new Guid("0679ceb5-3d4f-41f3-a1b0-b167e1ac6d7e"), 
     Name = "Another Guy", 
     Age = 39, 
     Organization = new Organization 
     { 
      Id = new Guid("b2ba06c9-5c00-4634-b6f7-80167ea8c3f1"), 
      Name = "TheCompany", 
      Number = 42 
     } 
    } 
}.AsQueryable();