我正在使用C#、. NET Core 2.2和Xunit框架。
当我在Web API控制器中执行以下代码并将其连接到真实数据库(SQL Server 2017)时,以下代码即方法“ GetTopFive”可以正常工作。
public class MovieRepository : IMovieRepository
{
private readonly MovieDbContext _moviesDbContext;
public MovieRepository(MovieDbContext moviesDbContext)
{
_moviesDbContext = moviesDbContext;
}
public IEnumerable<Movie> GetAll()
{
return _moviesDbContext.Movies;
}
public IEnumerable<MovieRating> GetTopFive()
{
var result = _moviesDbContext.Movies.Include(x => x.Ratings)
.Select(x => new MovieRating
{
Id = x.Id,
Title = x.Title,
Average = x.Ratings.Average(y => y.RatingValue)
}).OrderByDescending(x => x.Average).ThenBy(x => x.Title).Take(5).ToList();
return result;
}
}
但是当我运行测试时,我得到了这个错误:
Message: System.InvalidOperationException : Sequence contains no elements
这是测试代码,我使用内存数据库:
public class MovieRepositoryTest : IClassFixture<MovieSeedDataFixture>
{
private readonly IMovieRepository _sut;
private readonly MovieFilters _filters;
public MovieRepositoryTest(MovieSeedDataFixture fixture)
{
_sut = new MovieRepository(fixture.MovieContext);
_filters = new MovieFilters { Genre = "Action" };
}
[Fact]
public void GetTopFiveMovies_WhenCalled_ReturnsFiveMovies()
{
//Act
var movies = _sut.GetTopFive();
//Assert
Assert.Equal(5, movies.Count());
}
}
如果我通过删除“ OrderByDescending”来更改存储库,则它可以工作,但这不是我需要的结果:
public IEnumerable<MovieRating> GetTopFive()
{
var result = _moviesDbContext.Movies.Include(x => x.Ratings)
.Select(x => new MovieRating
{
Id = x.Id,
Title = x.Title,
Average = x.Ratings.Average(y => y.RatingValue)
}).Take(5).ToList();
return result;
}
这是灯具类,显然有数据:
public class MovieSeedDataFixture : IDisposable
{
public MovieDbContext MovieContext { get; }
public MovieSeedDataFixture()
{
var databaseName = "MovieListDatabase_" + DateTime.Now.ToFileTimeUtc();
var options = new DbContextOptionsBuilder<MovieDbContext>()
.UseInMemoryDatabase(databaseName)
.Options;
MovieContext = new MovieDbContext(options);
// Load movies
MovieContext.Movies.Add(new Movie { Id = 1, Title = "John Wick", YearOfRelease = 2015, Genre = "Action", RunningTime = 120 });
MovieContext.Movies.Add(new Movie { Id = 2, Title = "John Wick: Chapter 2", YearOfRelease = 2017, Genre = "Action", RunningTime = 130 });
MovieContext.Movies.Add(new Movie { Id = 3, Title = "Terminator 6", YearOfRelease = 2019, Genre = "Science Fiction/Action", RunningTime = 110 });
MovieContext.Movies.Add(new Movie { Id = 4, Title = "The Saint", YearOfRelease = 2017, Genre = "Action", RunningTime = 120 });
MovieContext.Movies.Add(new Movie { Id = 5, Title = "The Interview", YearOfRelease = 2014, Genre = "Action/Comedy", RunningTime = 120 });
MovieContext.Movies.Add(new Movie { Id = 6, Title = "Mr. & Mrs. Smith", YearOfRelease = 2005, Genre = "Crime/Thriller", RunningTime = 115 });
MovieContext.Movies.Add(new Movie { Id = 7, Title = "Fast & Furious 8", YearOfRelease = 2017, Genre = "Crime/Action", RunningTime = 125 });
MovieContext.Movies.Add(new Movie { Id = 8, Title = "Fast & Furious 1", YearOfRelease = 2001, Genre = "Crime/Action", RunningTime = 120 });
MovieContext.Movies.Add(new Movie { Id = 9, Title = "Jason Bourne", YearOfRelease = 2016, Genre = "Action", RunningTime = 135 });
MovieContext.Movies.Add(new Movie { Id = 10, Title = "Iron Man 3", YearOfRelease = 2013, Genre = "Science Fiction/Action", RunningTime = 110 });
// Load Users
MovieContext.Users.Add(new User { Id = 1, FirstName = "John", Lastname = "Doe" });
MovieContext.Users.Add(new User { Id = 2, FirstName = "Jane", Lastname = "Doe" });
// Load Ratings
MovieContext.Ratings.Add(new Rating { Id = 1, MovieId = 1, UserId = 1, RatingValue = 4 });
MovieContext.Ratings.Add(new Rating { Id = 2, MovieId = 1, UserId = 2, RatingValue = 5 });
MovieContext.Ratings.Add(new Rating { Id = 3, MovieId = 2, UserId = 1, RatingValue = 4 });
MovieContext.Ratings.Add(new Rating { Id = 4, MovieId = 2, UserId = 2, RatingValue = 4 });
MovieContext.Ratings.Add(new Rating { Id = 5, MovieId = 3, UserId = 1, RatingValue = 4 });
MovieContext.Ratings.Add(new Rating { Id = 6, MovieId = 3, UserId = 2, RatingValue = 4 });
MovieContext.Ratings.Add(new Rating { Id = 7, MovieId = 4, UserId = 1, RatingValue = 3 });
MovieContext.Ratings.Add(new Rating { Id = 8, MovieId = 4, UserId = 2, RatingValue = 3 });
MovieContext.Ratings.Add(new Rating { Id = 9, MovieId = 5, UserId = 1, RatingValue = 2 });
MovieContext.Ratings.Add(new Rating { Id = 10, MovieId = 5, UserId = 2, RatingValue = 2 });
MovieContext.Ratings.Add(new Rating { Id = 11, MovieId = 6, UserId = 1, RatingValue = 1 });
MovieContext.Ratings.Add(new Rating { Id = 12, MovieId = 6, UserId = 2, RatingValue = 1 });
MovieContext.SaveChanges();
}
public void Dispose()
{
MovieContext.Dispose();
}
}
有什么帮助我为什么会出现该错误? 谢谢
答案 0 :(得分:1)
问题与
有关Average = x.Ratings.Average(y => y.RatingValue)
并非所有电影都具有评级,因此Average()
会在空序列上抛出该异常。
如果您希望电影没有评级,则可以使用三元表达式:
Average = x.Ratings.Any() ? x.Ratings.Average(y => y.RatingValue) : 0 // or null depending on your model