While making some unit tests with mstest this error showed up when I set up UseInMemoryDatabase
. Important is that the error does not show up when I run the app. Only when running a test. It seems to come from here:
public List<string> WordProgress { get; set; } = new List<string>();
The error is gone when I add [NotMapped] above, but this makes the column dissapear.
Context:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<FinalWord>()
.HasMany(c => c.Games)
.WithOne(e => e.FinalWord);
modelBuilder.Entity<Game>()
.HasMany(c => c.GameWords)
.WithOne(e => e.Game);
modelBuilder.Entity<Game>()
.HasOne(c => c.FinalWord)
.WithMany(e => e.Games);
modelBuilder.Entity<Word>()
.HasMany(c => c.GameWords)
.WithOne(e => e.Word);
modelBuilder.Entity<GameWord>()
.HasOne(c => c.Game)
.WithMany(e => e.GameWords);
modelBuilder.Entity<GameWord>()
.HasOne(c => c.Word)
.WithMany(e => e.GameWords);
}
GameWord.cs
public class GameWord
{
[Key]
public int Id { get; set; }
public List<string> WordProgress { get; set; } = new List<string>();
[Required]
public Word Word { get; set; }
[Required]
public Game Game { get; set; }
public bool Finished { get; set; } = false;
}
And my test setup.
public UnitTest1()
{
DbContextOptionsBuilder<LingoContext> dbOptions = new DbContextOptionsBuilder<LingoContext>()
.UseInMemoryDatabase(
Guid.NewGuid().ToString()
);
_context = new LingoContext(dbOptions.Options);
}
[TestMethod]
public void GetAllGames()
{
var repo = new SqlGameRepo(_context);
Game game1 = new Game();
Game game2 = new Game();
_context.Game.Add(game1);
_context.Game.Add(game2);
_context.SaveChanges();
IEnumerable<Game> result = repo.GetAllGames();
Assert.AreEqual(result.Count(), 2);
}
Anyone knows the reason why?
CodePudding user response:
The error message is caused because the InMemoryDatabase provider does not support certain data types such as collections like List<>. The NotMapped attribute is used to indicate to the Entity framework that the property should not be mapped to the database.
This causes the column to disappear because the property is not being saved in the database and therefore it can't be retrieved. One way to fix this is to use a different database provider such as SQLite or SQL Server that supports the List<> data type, or you can refactor your code to use a different data structure that is supported by InMemoryDatabase such as an array or a HashSet.
Another solution is to create a private field and use a public property to access it, and create a constructor that initializes this field. This way the property is never null and the NotMapped attribute is not needed.