MSTest v2 和源 IQueryable 未使用 Entity Framework 核心实现 IAsyncEnumerable
MSTest v2 and The source IQueryable doesn't implement IAsyncEnumerable with Entity Framework Core
我正在尝试为 DAL 库(EF 核心)创建单元测试(MSTest v2)
数据服务
public IQueryable<BalanceDTO> GetCollection()
{
var entities = dbContext.Balance;
var dtos = mapper.Map<ICollection<BalanceDTO>>(entities).ToList();
dtos.ForEach(_d =>
{
_d.MonthSort = _d.Date.Month;
_d.MonthName = (new DateTimeFormatInfo()).GetMonthName(_d.MonthSort);
});
return dtos.AsQueryable();
}
public async Task<IList<BalanceDTO>> GetBalancesByYear(int year)
{
return await GetCollection().Where(_d => _d.Date.Year == year).OrderBy(_d => _d.MonthSort).ToListAsync();
}
测试
[TestMethod()]
[DataTestMethod]
[DataRow(2020, 2019)]
public void GetBalancesByYearTest(int found, int notfound)
{
var _configuration = new ConfigurationBuilder()
.SetBasePath(AssemblyProperties.AssemblyDirectory)
.AddJsonFile("appsettings.json")
.Build();
var optionsBuilder = new DbContextOptionsBuilder<AccountManagerContext>();
optionsBuilder.UseSqlServer(_configuration.GetConnectionString("AccountManagerLocalDB"));
var balanceDataService = new BalanceDataService(optionsBuilder);
var elementsFound = balanceDataService.GetBalancesByYear(found);
var elementsNotFound = balanceDataService.GetBalancesByYear(notfound);
Assert.IsNotNull(balanceDataService);
Assert.IsTrue(elementsFound.Result.Count > 0);
Assert.IsTrue(elementsNotFound.Result.Count == 0);
}
但是我得到这个错误:
InvalidOperationException: The source IQueryable doesn't implement IAsyncEnumerable<AccountManager.DAL.DTO.BalanceDTO>.
Only sources that implement IAsyncEnumerable can be used for Entity Framework asynchronous operations.
我找到了几个 link 但不知道如何解决这个问题。
How to overcome the IQueryable doesn't implement IAsyncQueryProvider while Mocking the FromSql() method?
知道如何为我的 DataService 方法创建测试吗?
Entity Framework 与 DbSet
一起工作,它们不仅仅是可查询的。
我最终得到了这个解决方案。
如果有人看到错误或需要改进的地方,我非常感谢任何建议。
public IQueryable<BalanceDTO> GetCollection()
{
var entities = dbContext.Balance;
var dtos = mapper.Map<ICollection<BalanceDTO>>(entities);
foreach(var _d in dtos)
{
_d.MonthSort = _d.Date.Month;
_d.MonthName = (new DateTimeFormatInfo()).GetMonthName(_d.MonthSort);
};
return dtos.AsQueryable();
}
public async Task<IList<BalanceDTO>> GetBalancesByYear(int year)
{
var entities = dbContext.Balance.Where(_d => _d.Date.Year == year).OrderBy(_d => _d.Date);
var balanceDTOs = Task<IList<BalanceDTO>>.Factory.StartNew(() =>
{
var dtos = mapper.Map<IList<BalanceDTO>>(entities);
foreach (var _d in dtos)
{
_d.MonthSort = _d.Date.Month;
_d.MonthName = (new DateTimeFormatInfo()).GetMonthName(_d.MonthSort);
};
return dtos;
});
return await balanceDTOs;
}
我已经修改了 GetBalancesByYear
所以它没有使用 GetCollection
因为如果它必须收集完整的元素集合并将它们转换成 DTO 就不会执行在过滤不需要的内容之前。
当我的 DAL 需要 return DTO 而不仅仅是实体时,我很困惑谁应该为我的 DAL 正确创建异步方法。
我正在尝试为 DAL 库(EF 核心)创建单元测试(MSTest v2)
数据服务
public IQueryable<BalanceDTO> GetCollection()
{
var entities = dbContext.Balance;
var dtos = mapper.Map<ICollection<BalanceDTO>>(entities).ToList();
dtos.ForEach(_d =>
{
_d.MonthSort = _d.Date.Month;
_d.MonthName = (new DateTimeFormatInfo()).GetMonthName(_d.MonthSort);
});
return dtos.AsQueryable();
}
public async Task<IList<BalanceDTO>> GetBalancesByYear(int year)
{
return await GetCollection().Where(_d => _d.Date.Year == year).OrderBy(_d => _d.MonthSort).ToListAsync();
}
测试
[TestMethod()]
[DataTestMethod]
[DataRow(2020, 2019)]
public void GetBalancesByYearTest(int found, int notfound)
{
var _configuration = new ConfigurationBuilder()
.SetBasePath(AssemblyProperties.AssemblyDirectory)
.AddJsonFile("appsettings.json")
.Build();
var optionsBuilder = new DbContextOptionsBuilder<AccountManagerContext>();
optionsBuilder.UseSqlServer(_configuration.GetConnectionString("AccountManagerLocalDB"));
var balanceDataService = new BalanceDataService(optionsBuilder);
var elementsFound = balanceDataService.GetBalancesByYear(found);
var elementsNotFound = balanceDataService.GetBalancesByYear(notfound);
Assert.IsNotNull(balanceDataService);
Assert.IsTrue(elementsFound.Result.Count > 0);
Assert.IsTrue(elementsNotFound.Result.Count == 0);
}
但是我得到这个错误:
InvalidOperationException: The source IQueryable doesn't implement IAsyncEnumerable<AccountManager.DAL.DTO.BalanceDTO>.
Only sources that implement IAsyncEnumerable can be used for Entity Framework asynchronous operations.
我找到了几个 link 但不知道如何解决这个问题。
How to overcome the IQueryable doesn't implement IAsyncQueryProvider while Mocking the FromSql() method?
知道如何为我的 DataService 方法创建测试吗?
Entity Framework 与 DbSet
一起工作,它们不仅仅是可查询的。
我最终得到了这个解决方案。 如果有人看到错误或需要改进的地方,我非常感谢任何建议。
public IQueryable<BalanceDTO> GetCollection()
{
var entities = dbContext.Balance;
var dtos = mapper.Map<ICollection<BalanceDTO>>(entities);
foreach(var _d in dtos)
{
_d.MonthSort = _d.Date.Month;
_d.MonthName = (new DateTimeFormatInfo()).GetMonthName(_d.MonthSort);
};
return dtos.AsQueryable();
}
public async Task<IList<BalanceDTO>> GetBalancesByYear(int year)
{
var entities = dbContext.Balance.Where(_d => _d.Date.Year == year).OrderBy(_d => _d.Date);
var balanceDTOs = Task<IList<BalanceDTO>>.Factory.StartNew(() =>
{
var dtos = mapper.Map<IList<BalanceDTO>>(entities);
foreach (var _d in dtos)
{
_d.MonthSort = _d.Date.Month;
_d.MonthName = (new DateTimeFormatInfo()).GetMonthName(_d.MonthSort);
};
return dtos;
});
return await balanceDTOs;
}
我已经修改了 GetBalancesByYear
所以它没有使用 GetCollection
因为如果它必须收集完整的元素集合并将它们转换成 DTO 就不会执行在过滤不需要的内容之前。
当我的 DAL 需要 return DTO 而不仅仅是实体时,我很困惑谁应该为我的 DAL 正确创建异步方法。