EF Core内存数据库中LINQ查询仅返回最后一个实体问题
EF Core 6.0.13按Mode过滤StopPoint仅返回单个实体的问题
我正在用Entity Framework Core 6.0.13开发一个返回数据库实体列表的方法,单元测试使用内存数据库填充测试数据,但按Mode过滤的查询只返回最后一个符合条件的实体,而非全部。
测试数据填充代码
private TopologyDBContext _topologyDbContext; private StopPointRepository _stopPointRepository; [SetUp] public void Setup() { // 创建内存测试数据库 var options = new DbContextOptionsBuilder<TopologyDBContext>() .UseInMemoryDatabase(databaseName: "TopologyTestDB") .Options; _topologyDbContext = new TopologyDBContext(options); _stopPointRepository = new StopPointRepository(_topologyDbContext); SeedTestData(); } [TearDown] public void TearDown() { _topologyDbContext.Database.EnsureDeleted(); } private void SeedTestData() { var typeCodeOne = new NaptanTypeCodes("RLY", "NaptanFerryBerth", false, "Ferry", "Stop", 85000); var typeCodeTwo = new NaptanTypeCodes("ntc2", "className2", false, "Air", "type2", 2); var typeCodeThree = new NaptanTypeCodes("ntc3", "className3", true, "BusCoach", "type3", 3); var typeCodeFour = new NaptanTypeCodes("ntc4", "className4", false, "BusCoach", "type4", 4); var typeCodeFive = new NaptanTypeCodes("ntc5", "className5", true, "BusCoach", "type5", 5); var modeFerry = new Mode("Ferry", "Description", null, null, true, null, null, null, null, null, true, null, DateTime.UtcNow, null, null, null, null, null, null, null); var modeAir = new Mode("Air", "Description", null, null, true, null, null, null, null, null, true, null, DateTime.UtcNow, null, null, null, null, null, null, null); var modeBusCoach = new Mode("BusCoach", "DescriptionOne", null, null, true, null, null, null, null, null, true, null, DateTime.UtcNow, null, null, null, null, null, null, null); var modeFerryList = new List<Mode>() {modeFerry}; var modeAirList = new List<Mode>() { modeAir}; var modeFerryAirList = new List<Mode>() { modeFerry, modeAir}; var modeBusCoachList = new List<Mode>() { modeBusCoach}; var stopPoint1 = new StopPoint("9100SIDCUP0", "Sidcup", "indicator1", "stopLetter1", 000, "910GSIDCUP", "RLY", 1, 2, 1001249, true, typeCodeOne, modeFerryList); _topologyDbContext.StopPoints.Add(stopPoint1); var stopPoint2 = new StopPoint("atco2", "commonName2", "indicator2", "stopLetter2", 2, "parentAtcoCode2", "ntc2", 3.3, 4.4, 2, false, typeCodeTwo, modeFerryAirList); _topologyDbContext.StopPoints.Add(stopPoint2); var stopPoint3 = new StopPoint("atco3", "commonName3", "indicator3", "stopLetter3", 3, "parentAtcoCode3", "discriminator3", 5.5, 6.6, 3, true, typeCodeThree, modeBusCoachList); _topologyDbContext.StopPoints.Add(stopPoint3); var stopPoint4 = new StopPoint("atco4", "commonName4", "indicator4", "stopLetter4", 4, "parentAtcoCode4", "discriminator4", 7.7, 8.8, 4, false, typeCodeFour, modeBusCoachList); _topologyDbContext.StopPoints.Add(stopPoint4); var stopPoint5 = new StopPoint("atco5", "commonName5", "indicator5", "stopLetter5", 5, "parentAtcoCode5", "discriminator5", 9.9, 10.1, 5, true, typeCodeFive, modeFerryList); _topologyDbContext.StopPoints.Add(stopPoint5); _topologyDbContext.SaveChanges(); }
测试用例情况
获取所有StopPoint的测试可以正常通过:
public async Task GetAllStopPoints_StopPointsInRepository_ReturnsAllStopPoints() { // Act var allStopPoints = await _stopPointRepository.GetAllStopPoints(); var firstStopPoint = allStopPoints.FirstOrDefault(); // Assert allStopPoints.Count().Should().Be(5); }
但按Mode过滤的测试无法通过,调试发现仅返回最后一个符合条件的实体(比如查询"BusCoach"时只返回StopPoint5,切换Mode后返回StopPoint4):
[Test] public async Task GetByModeStopPointsRequestAsync_GivenListOfModes_ReturnsBusCoachStopPointsOnly() { // Arrange var modes = new List<string> { "BusCoach" }; // Act var result = await _stopPointRepository.GetStopPointsByModeAsync(modes); var firstSp = result.First(); var secondSp = result.ElementAt(1); var thirdSp = result.ElementAt(2); var actual1 = firstSp.NaptanTypeCode.NaptanMode; var actual2 = secondSp.NaptanTypeCode.NaptanMode; var actual3 = thirdSp.NaptanTypeCode.NaptanMode; // Assert Assert.AreEqual(3, result.Count()); // 预期返回3个BusCoach类型的StopPoint Assert.That(actual1, Is.EqualTo("BusCoach")); Assert.That(actual2, Is.EqualTo("BusCoach")); Assert.That(actual3, Is.EqualTo("BusCoach")); }
查询方法实现
public async Task<IEnumerable<StopPoint>> GetStopPointsByModeAsync(IEnumerable<string> modes) { return await _dbSet .AsNoTracking() .Include(i => i.NaptanTypeCode.NaptanTypeCodesModes) .Include(i => i.Modes) .Where(n => n.Modes.Any(m => modes.Contains(m.Name))) .ToListAsync(); }
这个方法和获取所有StopPoint的方法结构一致,只是多了按Mode过滤的Where条件。尝试过批量添加StopPoint和逐个添加,问题依旧;也曾用foreach手动筛选,同样失败。推测问题出在LINQ过滤逻辑上,导致仅返回最后一个实体。
内容的提问来源于stack exchange,提问作者SaHu07
相关产品推荐
相关产品推荐

