问题
I have a DbContext
which has a Dbset
without Key. It works in the application, which only queries the table.
public class MyDbContext : DbContext, IMyDbContext
{
public MyDbContext(DbContextOptions<MyDbContext> options) : base(options) { }
public DbSet<MyEntity> MyEntities { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<MyEntity>().HasNoKey(); // No key
modelBuilder.ApplyConfigurationsFromAssembly(typeof(MyDbContext).Assembly);
}
}
I create the following test setup classes in the test project (xUnit):
public static class MyDbContextFactory
{
internal static MyDbContext Create()
{
var options = new DbContextOptionsBuilder<MyDbContext>()
.UseInMemoryDatabase(Guid.NewGuid().ToString())
.Options;
var context = new MyDbContext(options);
context.Database.EnsureCreated();
context.MyEnities.AddRange(new[] // This line got the error!!!
{
new MyEntity { Time = DateTime.Now, Instrument = "R1" },
new MyEntity { Time = DateTime.Now, Instrument = "R2" },
new MyEntity { Time = DateTime.Now, Instrument = "R3" },
});
context.SaveChanges();
return context;
}
}
public class QueryTestFixture : IDisposable
{
public MyDbContext MyDbContext { get; }
public IMapper Mapper { get; }
public QueryTestFixture()
{
MyDbContext = MyDbContextFactory.Create();
var configurationProvider = new MapperConfiguration(cfg =>
{
cfg.AddProfile<MappingProfile>();
});
Mapper = configurationProvider.CreateMapper();
}
public void Dispose()
{
// ... omitted ...
}
}
[CollectionDefinition("QueryTests")]
public class QueryCollection : ICollectionFixture<QueryTestFixture> { }
And here is the Test code.
[Collection("QueryTests")]
public class MyTest
{
private readonly MyDbContext _context;
private readonly IMapper _mapper;
public MyTest(QueryTestFixture fixture)
{
_context = fixture.MyDbContext;
_mapper = fixture.Mapper;
}
}
However, running any test method will get the following error before the tests are actually run. The error occurred on the line context.MyEnities.AddRange(....
above.
Message: System.AggregateException : One or more errors occurred. (Unable to track an instance of type 'MyEntity' because it does not have a primary key. Only entity types with primary keys may be tracked.) (The following constructor parameters did not have matching fixture data: QueryTestFixture fixture) ---- System.InvalidOperationException : Unable to track an instance of type 'MyEntity' because it does not have a primary key. Only entity types with primary keys may be tracked. ---- The following constructor parameters did not have matching fixture data: QueryTestFixture fixture Stack Trace: ----- Inner Stack Trace #1 (System.InvalidOperationException) ----- StateManager.GetOrCreateEntry(Object entity) DbContext.SetEntityStates(IEnumerable`1 entities, EntityState entityState) DbContext.AddRange(IEnumerable`1 entities) DbContext.AddRange(Object[] entities) InternalDbSet`1.AddRange(TEntity[] entities) MyDbContextFactory.Create() line 20 QueryTestFixture.ctor() line 16 ----- Inner Stack Trace #2 (Xunit.Sdk.TestClassException) -----
回答1:
Until now this is an open issue on Entity Framework: https://github.com/aspnet/EntityFramework.Docs/issues/898
You can not add new entities on a DbQuery or an DbSet with no key. I suggest you to keep track on this issue and for now mock your Context or to use Entity Framework Core Mock to accomplish that.
来源:https://stackoverflow.com/questions/59363290/error-on-initialize-a-dbset-without-key-unable-to-track-an-instance-of-type-my